pokročilé programování na platformě java, letní semestr...
TRANSCRIPT
Java, letní semestr 201330.4.2013
JAVAJAVA
Hibernate
Java, letní semestr 201330.4.2013
ORMORM● 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
Java, letní semestr 201330.4.2013
HibernateHibernate
zdroj obrázku: http://www.hibernate.org/
Java, letní semestr 201330.4.2013
ArchitekturaArchitektura
zdroj obrázku: http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html_single/
Java, letní semestr 201330.4.2013
Základní APIZá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é
Java, letní semestr 201330.4.2013
PoužitíPoužití● zjednodušeně
– vytvořit konfiguraci● XML
– vytvořit třídy● Java
– vytvořit mapovaní● XML nebo● Java anotace
Java, letní semestr 201330.4.2013
KonfiguraceKonfigurace● 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>
Java, letní semestr 201330.4.2013
Třídy pro persistentní dataTří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; }}
Java, letní semestr 201330.4.2013
Mapování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>
Java, letní semestr 201330.4.2013
Mapování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; }
@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; }}
● mapování lze i pomocí anotací
● v konfiguraci je pak v mapování přímo odkaz na třídu
Java, letní semestr 201330.4.2013
Používání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();
Java, letní semestr 201330.4.2013
Stavy objektů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
– persitentní objekt jehož session byla skončena– lze asociovat s novou session
Java, letní semestr 201330.4.2013
Používání objektů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();
Java, letní semestr 201330.4.2013
Používání objektů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);
Java, letní semestr 201330.4.2013
DotazováníDotazování● HQL – Hibernate query language
– obdoba SQL
select foofrom Foo foo, Bar barwhere foo.startDate = bar.date
● lze používat i nativní SQL
sess.createSQLQuery("SELECT * FROM CATS").list();
Java, letní semestr 201330.4.2013
Hibernate...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, letní semestr 201330.4.2013
JAVAJAVA
Unit testing
Java, letní semestr 201330.4.2013
ÚvodÚ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
Java, letní semestr 201330.4.2013
JUnitJUnit● 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
Java, letní semestr 201330.4.2013
Používání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ě
Java, letní semestr 201330.4.2013
PříkladPříkladpackage 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()); } }
Java, letní semestr 201330.4.2013
AssertAssert● 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
Java, letní semestr 201330.4.2013
Testování výjimekTestování výjimek● jak otestovat „správné“ vyhazování výjimek?
@Test(expected= IndexOutOfBoundsException.class) public void empty() { new ArrayList<Object>().get(0); }
Java, letní semestr 201330.4.2013
Spouštění testů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
Java, letní semestr 201330.4.2013
TestNGTestNG● http://testng.org/● inspirováno JUnit frameworkem● má více možností než JUnit
– např.
Java, letní semestr 201330.4.2013
JAVAJAVA
Maven
Java, letní semestr 201330.4.2013
PřehledPř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ů– …
Java, letní semestr 201330.4.2013
Používání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
Java, letní semestr 201330.4.2013
Struktura projektuStruktura projektu
my-app|-- pom.xml`-- src |-- main | `-- java | `-- com | `-- mycompany | `-- app | `-- App.java `-- test `-- java `-- com `-- mycompany `-- app `-- AppTest.java
Java, letní semestr 201330.4.2013
POM – Project Object ModelPOM – 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>
Java, letní semestr 201330.4.2013
Životní cyklus „buildu“Ž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
Java, letní semestr 201330.4.2013
Další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í dokumentacemvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-site -DgroupId=com.mycompany.app -DartifactId=my-app-site
Java, letní semestr 201330.4.2013
JAVAJAVA
Apache Ivy
Java, letní semestr 201330.4.2013
PřehledPřehled● http://ant.apache.org/ivy● správa závislostí● rozšíření pro Ant
– lze použít i samostatně● „lightweight“ maven
Java, letní semestr 201330.4.2013
Použití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>
Java, letní semestr 201330.4.2013
ZávislostiZávislosti● implicitně se používají maven repozitáře● lze definovat vlastní
– local– shared– public