International festival of contemporary cicrus and theatre LETNÍ LETNÁ
Pokročilé programování na platformě Java, letní semestr...
Transcript of Pokročilé programování na platformě Java, letní semestr...
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