JAVA Hibernate
ORM Object/Relational Mapping mapovaní mezi objekty a záznamy v relační databázi zjednodušeně třída ~ schéma tabulky objekt ~ řádek v tabulce ORM udržuje vazby mezi objektem a řádkem v tabulce změna v objektu změna v DB Hibernate http://www.hibernate.org/ dříve ORM pro Javu dnes ORM plus další knihovny a nástroje pro Javu a.net
Hibernate zdroj obrázku: http://www.hibernate.org/
Architektura zdroj obrázku: http://docs.jboss.org/hibernate/orm/4.3/manual/en-us/html_single/
Základní API Session propojení mezi DB a aplikací schovává v sobě spojení do DB JDBC connection spravuje objekty obsahuje cache objektů SessionFactory tvůrce session obsahuje mapovaní mezi objekty a DB může obsahovat cache objektů persistentní objekty obyčejné Java objekty POJO/JavaBeans měly by dodržovat pravidla pro JavaBeans ale není to nutné
Použití zjednodušeně vytvořit konfiguraci XML vytvořit třídy Java vytvořit mapovaní XML nebo Java anotace
Konfigurace XML soubor definuje připojení do DB typ (dialekt) DB kde je mapovaní <hibernate-configuration> <session-factory> <property name="connection.driver_class">org.h2.driver</property> <property name="connection.url">jdbc:h2:mem:db1;db_close_delay=-1;mvcc=true</property> <property name="connection.username">sa</property> <property name="connection.password"/> <property name="connection.pool_size">1</property> <property name="dialect">org.hibernate.dialect.h2dialect</property> <property name="cache.provider_class">org.hibernate.cache.nocacheprovider</property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">create</property> <mapping resource="org/hibernate/tutorial/hbm/event.hbm.xml"/> </session-factory> </hibernate-configuration>
Třídy pro persistentní data POJO měly by dodržovat pravidla pro JavaBeans není nutné je potřeba konstruktor bez parametrů jeho viditelnost je libovolná public class Event { private Long id; private String title; private Date date; public Event() {} public Event(String title, Date date) { this.title = title; this.date = date; } public Long getid() { return id; } private void setid(long id) { this.id = id; } public Date getdate() { return date; } public void setdate(date date) { this.date = date; } public String gettitle() { return title; } public void settitle(string title) { this.title = title; } }
Mapování XML soubor mapování atributů třídy na sloupce definuje se jméno typ není nutný, pokud je zřejmý Hibernate typy nejsou to ani Java ani SQL typy jsou to převodníky mezi Java a SQL typy sloupec není nutný pokud je stejný jako jméno <hibernate-mapping package="org.hibernate.tutorial.hbm"> <class name="event" table="events"> <id name="id" column="event_id"> <generator class="increment"/> </id> <property name="date" type="timestamp" column="event_date"/> <property name="title"/> </class> </hibernate-mapping>
Mapování @Entity @Table( name = "EVENTS" ) public class Event { private Long id; private String title; private Date date; public Event() { } public Event(String title, Date date) { this.title = title; this.date = date; } mapování lze i pomocí anotací v konfiguraci je pak v mapování přímo odkaz na třídu @Id @GeneratedValue(generator="increment") @GenericGenerator(name="increment", strategy = "increment") public Long getid() { return id; } private void setid(long id) { this.id = id; } @Temporal(TemporalType.TIMESTAMP) @Column(name = "EVENT_DATE") public Date getdate() { return date; } public void setdate(date date) { this.date = date; } } public String gettitle() { return title; } public void settitle(string title) { this.title = title; }
Používání SessionFactory sessionfactory = new Configuration().configure().buildSessionFactory(); Session session = sessionfactory.opensession(); session.begintransaction(); session.save(new Event("Our very first event!", new Date())); session.save(new Event("A follow up event", new Date())); session.gettransaction().commit(); session.close(); List result = session.createquery( "from Event" ).list();
Stavy objektů Transient vytvořený objekt (new) ale ještě neasociovaný s Hibernate session Persistent objekt asociovaný se session vytvořený a pak uloženy nebo načtený Detached perzistentní objekt jehož session byla skončena lze asociovat s novou session
Používání objektů načítání sess.load( Event.class, new Long(id) ); při neexistenci vyhazuje výjimku nemusí nutně sahat ihned do DB sess.get( Event.class, new Long(id) ); při neexistenci vrací null dotazování sess.createquery(...).list() modifikování objektů Event e = sess.load( Event.class, new Long(69) ); e.set... sess.flush();
Používání objektů modifikace odpojených objektů Event e = sess.load( Event.class, new Long(69) ); e.set...... secondsess.update(e); mazání objektů sess.delete(e);
Dotazování HQL Hibernate query language obdoba SQL select foo from Foo foo, Bar bar where foo.startdate = bar.date lze používat i nativní SQL sess.createsqlquery("select * FROM CATS").list();
Hibernate... další součásti vytváření tříd podle tabulek podpora pro full-text vyhledávání verzování objektů validace objektů podpora JPA (Java Persistence API)...
JAVA Unit testing
Úvod unit testing testování malý jednotek funkčnosti jednotka nezávislá na ostatních testování zcela oddělené vytvářejí se pomocné objekty pro testování kontext typicky v OO jazycích jednotka ~ metoda ideálně unit testy pro všechny jednotky v programu typicky v OO jazycích pro všechny public metody
JUnit podpora pro unit testing v Javě http://www.junit.org/ aktuální verze 4 používání založeno na anotacích starší verze založeno na dědičnosti a jmenných konvencích
Používání testovací metody označeny anotací @Test JUnit se spustí na množinu tříd najde v nich metody označené @Test ty provede další anotace @Before metoda prováděná před každým testem určeno pro přípravu prostředí @After metoda provádění po každém testu určeno pro úklid @BeforeClass metoda prováděná před všemi testy na dané třídě @AfterClass metoda prováděná po všech testech na dané třídě
Příklad package junitfaq; import org.junit.*; import static org.junit.assert.*; import java.util.*; public class SimpleTest { private Collection collection; @BeforeClass public static void onetimesetup() { // one-time initialization code } @AfterClass public static void onetimeteardown() { // one-time cleanup code } @Before public void setup() { collection = new ArrayList(); } } @After public void teardown() { collection.clear(); } @Test public void testemptycollection() { asserttrue(collection.isempty()); } @Test public void testoneitemcollection() { collection.add("itema"); assertequals(1, collection.size()); }
Assert asserttrue assertfalse assertequals assert... statické metody na org.junit.assert ověřování podmínek v testech test selže pokud assert... selže assert...() vyhodí AssertionError obecně test je splněn, pokud metoda skončí normálně test není splněn, pokud metoda vyhodí výjimku
Testování výjimek jak otestovat správné vyhazování výjimek? @Test(expected= IndexOutOfBoundsException.class) public void empty() { new ArrayList<Object>().get(0); }
Spouštění testů z kódu org.junit.runner.junitcore.runclasses(testclass1.class,...); z příkazové řádky java org.junit.runner.junitcore TestClass1 [další třídy...] z Antu task junit <junit printsummary="yes" fork="yes" haltonfailure="yes"> <formatter type="plain"/> <test name="my.test.testcase"/> </junit> z IDE
TestNG http://testng.org/ inspirováno JUnit frameworkem má více možností než JUnit např. parametry testovacích metod základní použití je stejné
JAVA Maven
Přehled http://maven.apache.org/ nástroj pro správu projektů zjednodušeně si lze představit jako rozšíření Antu ale není to rozšíření Antu poskytuje správu závislostí usnadnění překládání (build) projektů používání best practices přidávání nových modulů
Používání vygenerování struktury projektu mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.mycompany.app -DartifactId=my-app archetype ~ šablona projektu vygeneruje následující strukturu
Struktura projektu my-app -- pom.xml `-- src -- main `-- java `-- com `-- mycompany `-- app `-- App.java `-- test `-- java `-- com `-- mycompany `-- app `-- AppTest.java
POM Project Object Model definice projektu <project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelversion>4.0.0</modelversion> <groupid>com.mycompany.app</groupid> <artifactid>my-app</artifactid> <packaging>jar</packaging> <version>1.0-snapshot</version> <name>maven Quick Start Archetype</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupid>junit</groupid> <artifactid>junit</artifactid> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies> </project>
Životní cyklus buildu mvn fáze vždy se provedou i předchozí fáze 1. process-resources 2. compile 3. process-test-resources 4. test-compile 5. test 6. package 7. install 8. deploy
Další generování jiných typů projektů mvn archetype:generate \ -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=com.mycompany.app -DartifactId=my-webapp generování dokumentace mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-site -DgroupId=com.mycompany.app -DartifactId=my-app-site
JAVA Apache Ivy
Přehled http://ant.apache.org/ivy správa závislostí rozšíření pro Ant lze použít i samostatně lightweight maven
Použití závislosti v souboru ivy.xml <ivy-module version="2.0"> <info organisation="org.apache" module="hello-ivy"/> <dependencies> <dependency org="commons-lang" name="commons-lang" rev="2.0"/> <dependency org="commons-cli" name="commons-cli" rev="1.0"/> </dependencies> </ivy-module> build.xml <project xmlns:ivy="antlib:org.apache.ivy.ant" name="hello-ivy" default="run"> <target name="resolve" description="retrieve dependencies with ivy"> <ivy:retrieve /> </target> </project>
Závislosti implicitně se používají maven repozitáře lze definovat vlastní local shared public
Java, letní semestr Verze prezentace 2015 AJ13.cz.2015.01 Tato prezentace podléhá licenci Creative Commons Uveďte autora-neužívejte komerčně 4.0 Mezinárodní License. 37