Tajti Ákos http://cesjava.freeblog.hu
<ul><li>az objektum-perzisztenciát biztosító eszköz  </li></ul><ul><li>segítségével adatbázistáblák helyett osztályokkal d...
Ha az osztályainkat le akarjuk képezni adatbázistáblákra, akkor meg kell adnunk egy ún.  mapping  fájlban, hogy az egyes o...
Az előző osztályhoz tartozó mapping állomány: <?xml version=&quot;1.0&quot;?> <!DOCTYPE hibernate-mapping PUBLIC &quot;-//...
A mappingeket automatikusan generálhatjuk az adatbázis alapján. A későbbi  ant script alapján. A projekt könyvtárában adju...
Amikor az adatbázisra leképezzük a projektünk osztályait, feldolgozásra kerülnek a mapping állományok:  betöltődnek az egy...
Egyszálú, rövidéletű  objektum, ami egy párbeszédet reprezentál az alkalmazás és a perzisztens tárolóhely között. Azaz az ...
A  Session   JDBC kapcsolatokat csomagol be  (azaz nem nekünk kell a kapcsolatot létrehozni, hanem minden  Session -höz já...
Egyszálú, rövid életű objektum, amit arra használhatunk az alkalmazásban, hogy a munka  atomi lépéseit  specifikáljuk (aza...
… Transaction t = sess.beginTransaction()‏   Example e = (Example)sess.load(19);   e.setS(”test”);   //elmentjük e-t   ses...
Egy perzisztens osztály (ami le van képezve adatbázisra) három állapotban  lehet (egyszerre persze csak egyben): <ul><li>t...
//itt az objektum még tranziens, hiszen nem rendeltük hozzá  /Sessiönhöz Example e = new Example(); e.setI(10); Session se...
A hibernate az objektum-perzisztenciát biztosító eszköz. Az objektumok  leképezéséhez mapping állományokat használ. A  map...
org.hibernate.SessionFactory openSession(): Elkészít egy adatbázis-kapcsolatot és létrehoz egy olyan  Session -t, ami ezt ...
org.hibernate.Session beginTransaction(): Elindít egy munkaegységet, és visszaadja a hozzá tartozó  Transaction  példányt ...
org.hibernate.Session flush(): Flush-re kényszeríti a  Session -t. Ilyenkor minden DML utasítás lefut, amit a hibernate op...
org.hibernate.Session load(Class c, Serializable id): Betölti és visszaadja a  c  osztályhoz tartozó táblából azt a sort, ...
persist(Object o): Elmenti az  o  objektumot az adatbázisba, de nem adja vissza a hozzá rendelt id-t. org.hibernate.Sessio...
org.hibernate.Transaction commit(): Befejezi a munkaegységet, és a szülő  Session -ön végrehajt egy flush hívást, kivéve, ...
Minden olyan metódus, ami a  Transaction  példányok manipulálásával vagy DML műveletekkel valamilyen kapcsolatban van,  Hi...
Szituáció: A cégnek egy olyan alkalmazásra van szüksége, amivel nagyon fontos  Example  objektumokat tudunk perzisztenssé ...
Importáljuk a szükséges osztályokat: package tajti.ex; //a hibernate osztályai import org.hibernate.Session; import org.hi...
A kódba érdemes először beletennünk a szokásos kivételkezelő részt: Session sess = null; Transaction trans = null; try{ //...
A logikát megvalósító kód: //a sessiont a sessionfaktory példányosítja sess = SessionFactoryFactory.buildSessionFactory()‏...
//új atomi munkaegységet kezdünk, mert az előző végetért trans.begin(); //és újra mentünk sess.save(example); //és újra ko...
A hibernate konfigurációjához három helyen szólhatunk hozzá: <ul><li>hibernate.cfg.xml </li></ul><ul><li>Ezt automatikusan...
A legfontosabb propertyk: hibernate.connection.driver_class Az adatbázisunkhoz tartozó JDBC driver neve. Pl.:  oracle.jdbc...
hibernate.show_sql   Ha értéke  true , akkor munden DML művelet esetén mutatja a használt SQL utasítást. hibernate.order_u...
Amit láttatok, az a hibernatenek csak egy része – az alapok. Sok metódusnak sokkal több túlterhelése van, és van olyan, am...
Upcoming SlideShare
Loading in...5
×

Hibernate tutorial

7,259

Published on

hibernate bevezető. bővebben itt: http://cesjava.freeblog.hu

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
7,259
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
191
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Hibernate tutorial

  1. 1. Tajti Ákos http://cesjava.freeblog.hu
  2. 2. <ul><li>az objektum-perzisztenciát biztosító eszköz </li></ul><ul><li>segítségével adatbázistáblák helyett osztályokkal dolgozhatunk </li></ul><ul><li>a lekérdezésekben táblák helyett osztályneveket használhatunk, de ha </li></ul><ul><li>nagyon muszáj, írhatunk SQL lekérdezéseket is </li></ul>A lényeg: A hibernate elrejti előlünk a fizikai adatbázist
  3. 3. Ha az osztályainkat le akarjuk képezni adatbázistáblákra, akkor meg kell adnunk egy ún. mapping fájlban, hogy az egyes osztályoknak milyen tábla feleltethető meg, az egyes tábláknak mik az elsődleges kulcsai stb. Példa: package tajti.ex; public class Example{ … protected Integer i; protected String s; … } <ul><li>A hibernate csak olyan osztályokat képes leképezni, amelyekben: </li></ul><ul><li>az adattagok típusa nem primitív típus </li></ul><ul><li>minden kollekció típusú adattagnál valamelyik kollekció interfészt adjuk meg </li></ul><ul><li>típusnak (Map, List stb.)‏ </li></ul><ul><li>minden leképezni kívánt adattagnak (amit az adatbázistábla egyik oszlopaként </li></ul><ul><li>meg akarunk jeleníteni) van getter és setter metódusa </li></ul>
  4. 4. Az előző osztályhoz tartozó mapping állomány: <?xml version=&quot;1.0&quot;?> <!DOCTYPE hibernate-mapping PUBLIC &quot;-//Hibernate/Hibernate Mapping DTD 3.0//EN&quot; &quot;http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&quot; > <hibernate-mapping> <class name= &quot;tajti.ex.Example&quot; table= &quot;EXAMPLE&quot;> <id name= &quot; i &quot; type=&quot;java.lang.Integer&quot; column=&quot;ID&quot;> <generator class=&quot;sequence&quot;> <param name=&quot;sequence&quot;>f3t_seq</param> </generator> </id> <property name= &quot; s&quot; type= &quot; string&quot; column=„S&quot; not-null=&quot;true&quot; length=&quot;15&quot; /> </class> </hibernate-mapping>
  5. 5. A mappingeket automatikusan generálhatjuk az adatbázis alapján. A későbbi ant script alapján. A projekt könyvtárában adjuk ki ezt a parancsot: ant generate.hbm Ekkor a model alkönyvtárban megtaláljuk majd a mappingeket. A hibernate konfigurációs fájlját a következő utasítás állítja elő: ant generate.cfg Ezt mindig aktualizálni kell, ha új mappingeket készítünk vagy generálunk.
  6. 6. Amikor az adatbázisra leképezzük a projektünk osztályait, feldolgozásra kerülnek a mapping állományok: betöltődnek az egyes osztályok metaadatai, ellenőrizni kell, hogy az adatbázis szerkezete megfelel-e az osztályok szerkezetének stb. Ezután a mappingekből beolvasott adatok bekerülnek egy SessionFactory példányba. A SessionFactory tehát tárolja az objektumok perzisztenssé tételéhez szükséges információkat. Mivel a SessionFactory felépítése nagyon időigényes, minden adatbázishoz csak egy példányt érdemes elkészíteni, amit minden osztály használ (singleton). A példában ezt a singletont a SessionFactoryFactory osztály kezeli. A SessionFactory tartalmazhat másodlagos cache-t (paraméterrel állítható).
  7. 7. Egyszálú, rövidéletű objektum, ami egy párbeszédet reprezentál az alkalmazás és a perzisztens tárolóhely között. Azaz az objektumok perzisztenssé tétele mindig egy Session -ön belül történik, ugyanígy a kiolvasás is. Példa: … Example e = new Example(); e.setI(15); //létrehozunk egy Sessiont (aminek a faktorija a SessionFactory)‏ Session sess = SessionFactoryFactory.buildSessionFactory()‏ . openSession() ; Transaction t = sess.beginTransaction() ; //Így menthetünk el egy leképezett objektumot sess.save(e) ; t.commit(); …
  8. 8. A Session JDBC kapcsolatokat csomagol be (azaz nem nekünk kell a kapcsolatot létrehozni, hanem minden Session -höz jár egy). Minden Session kötelezően tartalmaz elsődleges cache-t . Azaz: ha az alkalmazás futása során egy Session -ön belül lekérdeztünk már egy objektumot, akkor az a memóriában marad, és legközelebb onnan kapjuk meg (persze ez befolyásolható lockolással). Megjegyzés: a hibernate csak akkor nyúl az adatbázishoz, ha tényleg szükség van rá, mi nem is tudhatjuk, hogy mikor (kivéve ha kikényszerítjük a flush metódussal (lásd később)).
  9. 9. Egyszálú, rövid életű objektum, amit arra használhatunk az alkalmazásban, hogy a munka atomi lépéseit specifikáljuk (azaz meghatározzuk, mely adatbázis-műveleteknek kell egy megbonthatatlan egységként végrehajtódniuk). Elrejti a programozó elől a használt JDBC, JTA vagy CORBA tranzakciókat. Azaz: nem kell ezeknek az API-knak az osztályait használnunk a tranzakciók kezeléséhez, mert a hibernate elintézi ezt nekünk, ha megmondjuk, hogy JDBC, JTA vagy CORBA tranzakciókat használjon. Fontos: a tranzakció demarkáció mindig kötelező . Azaz: ahányszor módosítani akarjuk az adatbázist, mindig el kell indítanunk egy új tranzakciót, és a végén commitálnunk vagy visszagörgetnünk (persze nem úgy kell érteni, hogy minden insert, update és delete egy új tranzakcióba kerüljön; csak az elemi lépéseknek (amik több műveletből állhatnak) kell új tranzakció).
  10. 10. … Transaction t = sess.beginTransaction()‏ Example e = (Example)sess.load(19); e.setS(”test”); //elmentjük e-t sess.save(Example.class, e); //kitöröljük a e-t sess.delete(e); //kommitálunk trans.commit(); … Ha a következő kódrészletből a vastag részek hiányoznának, kivételt kapnánk (csak akkor elnéző a hibernate, ha tranzakció-kezelőnek a beállításoknál a JDBCTransactionFactory-t adjuk meg (lásd később));
  11. 11. Egy perzisztens osztály (ami le van képezve adatbázisra) három állapotban lehet (egyszerre persze csak egyben): <ul><li>tranziens: az objektumot még soha nem mentettük az adatbázisba, nincs </li></ul><ul><li>elsődleges kulcsértéke. </li></ul><ul><li>perzisztens: a példány egy Session -ben élő objektum, amit már elmentettünk. </li></ul><ul><li>Létezik elsődleges kulcsértéke és esetleg egy sor hozzá az adatbázisban. A </li></ul><ul><li>hibernate garantálja, hogy egy Session -ön belül a perzisztencia id megegyezik </li></ul><ul><li>a Java id-vel, azaz használhatjuk az == operátort egyenlőségvizsgálatra. </li></ul><ul><li>detached: az objektumot egyszer kapcsolatban volt egy Session-nel, de azt a </li></ul><ul><li>Session-t már lezártuk, vagy egy másik folyamatban szerializáltuk a példányt. </li></ul>Tranziens Perzistens Detached új gc
  12. 12. //itt az objektum még tranziens, hiszen nem rendeltük hozzá /Sessiönhöz Example e = new Example(); e.setI(10); Session sess = SessionFactoryFactory.buildSessionFactory()‏ .openSession(); Transaction trans = sess.beginTransaction(); //itt az objektum perziszetenssé válik (elmentjük)‏ sess.save(e); //betöltjük azt az objektumot, aminek az id-je 10 Example e2 = (Example)sess.load(Example.class, 10); //ez most igazat ad vissza e == e2; trans.commit(); sess.close(); //lezárjuk a Sessiönt //az objektum itt már detached . Ha a tranzakción belül kitöröltük //volna az adatbázisból,akkor most tranziens lenne.
  13. 13. A hibernate az objektum-perzisztenciát biztosító eszköz. Az objektumok leképezéséhez mapping állományokat használ. A mapping fájlok alapján felépül egy SessionFactory példány, amiből minden adatbázishoz csak egyre van szükség. A SessionFactory állítja elő nekünk azokat a Session objektumokat, amiken keresztül ténylegesen kommunikálhatunk az adatbázissal. A Sessionben olyan típusú objektumokat menthetük/törölhetünk/frissíthetünk, amely típusokat a mappingek segítségével leképeztük az adatbázisra. A Session továbbá futásidejű konzisztenciát biztosít, és elsődleges cache -t kínál a programozónak. Fontos interfész a Transaction is, ugyanis ezzel hordozhatóbbá válik az alkalmazásunk.
  14. 14. org.hibernate.SessionFactory openSession(): Elkészít egy adatbázis-kapcsolatot és létrehoz egy olyan Session -t, ami ezt a kapcsolatot csomagolja be. openSession(Connection conn): Létrehoz egy olyan Session-t, ami a paraméterként megkapott Connection példányt csomagolja be. Akkor lehet rá szükségünk, ha a JDBC és a hibernate API-t vegyesen akarjuk használni. evict(): kitöröl minden entitást a másodlagos cache-ből. close(): Megsemmisíti a példányt, és felszabadítja minden erőforrását.
  15. 15. org.hibernate.Session beginTransaction(): Elindít egy munkaegységet, és visszaadja a hozzá tartozó Transaction példányt (azaz példányosítja a Transaction osztályt). close(): Lezárja a példányt és a hozzá tartozó JDBC kapcsolatot. createQuery(String hqlQuery): Elkészít egy futtatható Query példányt a paraméterül kapott HQL lekérdezés alapján. createSQLQuery(String sql): Elkészít egy futtatható SQLQuery példányt a paraméterül kapott SQL lekérdezés alapján. delete(Object o): Eltávolít egy perzisztens objektumot az adatbázisból.
  16. 16. org.hibernate.Session flush(): Flush-re kényszeríti a Session -t. Ilyenkor minden DML utasítás lefut, amit a hibernate optimalizációs okokból (hogy minél kevesebbszer kelljen a DB-t lekérdezés futtatására kérni) „visszatartott”. A metódus meghívása után biztosak lehetünk benne, hogy nincs piszkos adatunk. get(Class c, Serializable id): Visszaadja a megadott id-jű példányát a c osztálynak ( Object típussal) ha van ilyen, különben nullt. A load -tól abban különbözik, hogy mindenképpen az adatbázishoz nyúl, míg a load csak ún. proxy osztályt készít el. get(Class c, Serializable s, LockMode lm): Ugyanaz, mint az előző , csak a harmadik paraméter szerint lockol. getIndentity(Object o): Visszaadja azt az id-t ( Serializable ), ami a Sessionben belül a megadott objektumhoz tartozik.
  17. 17. org.hibernate.Session load(Class c, Serializable id): Betölti és visszaadja a c osztályhoz tartozó táblából azt a sort, amiben az azonosító értéke id . Ha a konfigurációs fájlban meg nem változtatjuk ezt, akkor a hibernate alapesetben csak egy ún. proxyt tölt be. Azaz nem nyúl az adatbázishoz, hanem csak elkészít egy c típusú példányt, és annak azonosítóját beállítja id -re. Ezzel sok fölösleges lekérdezés elkerülhető, például ha csak azért kell az objektum, hogy egy másik objektumban hivatkozzunk rá. Ezt nevezik „ lazy loading” -nak. refresh(Object o): Újra beolvassa az o objektum állapotát az adatbázisból. save(Object o): Egy adatbázisbeli egyedi azonosítót rendel az objektumhoz (aminek a generálási módja a mapping állományokban van megadva), elmenti azt az adatbázisba, majd visszatér az azonosítóval ( Serializable ).
  18. 18. persist(Object o): Elmenti az o objektumot az adatbázisba, de nem adja vissza a hozzá rendelt id-t. org.hibernate.Session update(Object o): Frissíti azt a perzisztens objektumot ( o állapotával), aminek az azonosítója megegyezik a megadott tranziens objektum, o , Session -beli azonosítójával. saveOrUpdate(Object o): save(o) vagy update(o) , attól függően, hogy az objektumot korábban perzisztenssé tettük-e már, vagy még nem. delete(Object o): Eltávolítja a perzisztens o objektumot az adatbázisból.
  19. 19. org.hibernate.Transaction commit(): Befejezi a munkaegységet, és a szülő Session -ön végrehajt egy flush hívást, kivéve, ha a FlushMode.NEVER flushmód be van állítva. rollback(): Visszagörgeti a tranzakciót. wasCommitted(), wasRolledBack(): Elmenti, hogy a tranzakciót kommitálták-e, illetve visszagörgették-e. begin(): Új tranzakcióba kezd. setTimeout(int secs): Beállítja, hogy legfeljebb hány másodpercig futhatnak azok a tranzakciók, amiket a begin hívásokkal (a példányon) indítanak el.
  20. 20. Minden olyan metódus, ami a Transaction példányok manipulálásával vagy DML műveletekkel valamilyen kapcsolatban van, HibernateException kivételt dob. Emiatt minden olyan kódot, amiben a hibernate API-t használjuk, kivételkezelő blokkban kell elhelyezni, aminek a catch ágában vissza kell görgetni a tranzakciót (mert nem sikerült), a finally ágban pedig mindig le kell zárni a Session -t: Session sess = null; Transaction trans = null; try{ //a hibernate apit használó kód }catch(HibernateException ex){ if(trans != null) //ez maradhat null, ha gond van try{ //a tranzakció metóusai is dobhatnak trans.rollback(); }catch(HibernateException e){ } }finally{ if(sess != null) try{ //a session metódusai is dobhatnak sess.close(); }catch(HibernateException e){ } }
  21. 21. Szituáció: A cégnek egy olyan alkalmazásra van szüksége, amivel nagyon fontos Example objektumokat tudunk perzisztenssé tenni. Egyelőre csak az látszik, hogy menteni kell tudni a példányokat, de mi előrelátóak vagyunk, és készítünk egy olyan alkalmazást, ami elemi műveletként elmenti, frissíti, törli az objektumokat, majd egy másik elemi műveletben újra elmenti azokat. Speciális követelmény, hogy az alkalmazásnak, ha nem sikerül a művelet, a következő szöveget kell a szabványos kimenetre írnia: Muck, You Lose!
  22. 22. Importáljuk a szükséges osztályokat: package tajti.ex; //a hibernate osztályai import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.HibernateException; //a saját osztályunk a SessionFactory előállításához import faktum3t.appserv.server.logic.SessionFactoryFactory; Ezután a szokásos dolgok jönnek: public class ExampleApp{ public static void saveIt(Example example){ //ide jön majd a kód } }
  23. 23. A kódba érdemes először beletennünk a szokásos kivételkezelő részt: Session sess = null; Transaction trans = null; try{ //ide jön majd a logikát megvalósító kód }catch(HibernateException ex){ System.out.println(„Muck, You Lose!”); if(trans != null) //ez maradhat null, ha gond van try{ //a tranzakció metóusai is dobhatnak trans.rollback(); }catch(HibernateException e){ } }finally{ if(sess != null) try{ //a session metódusai is dobjatnak sess.close(); }catch(HibernateException e){ } }
  24. 24. A logikát megvalósító kód: //a sessiont a sessionfaktory példányosítja sess = SessionFactoryFactory.buildSessionFactory()‏ .openSession(); //a transaction a sess példányhoz van rendelve trans = sess.beginTransaction(); //elmentjük az example objektumot sess.save(example); //nagybetűssé alakítja az s adattagot example.setS(example.getS().toUpperCase()); //majd frissít sess.update(s); //majd töröl sess.delete(s); trans.commit();
  25. 25. //új atomi munkaegységet kezdünk, mert az előző végetért trans.begin(); //és újra mentünk sess.save(example); //és újra kommitálunk trans.commit(); Az alkalmazás a követelményeknek megfelel 
  26. 26. A hibernate konfigurációjához három helyen szólhatunk hozzá: <ul><li>hibernate.cfg.xml </li></ul><ul><li>Ezt automatikusan generálható egy ant scripttel. Ebben a fájlban </li></ul><ul><li>le van írva, hogy melyik osztályt melyik mapping állomány képezi le. </li></ul><ul><li>hibernate.properties </li></ul><ul><li>Minden beállítás, amit ebben az állományban adunk meg, megadható az </li></ul><ul><li>előzőben is: </li></ul>propertynév=valami -> <property name=”propertynév”>valami</property> <ul><li>a hibernate API-n keresztül </li></ul><ul><li>Ezt most hagyjuk. </li></ul>
  27. 27. A legfontosabb propertyk: hibernate.connection.driver_class Az adatbázisunkhoz tartozó JDBC driver neve. Pl.: oracle.jdbc.OracleDriver hibernate.connection.url A JDBC kapcsolat URL-je, amin keresztül a DB elérhető. Adatbázisgyártónként eltérő. Pl.: jdbc:oracle:thin:@192.168.12.26:1521:faktum hibernate.connection.username Az adatbázis használatához szükséges felhasználónév hibernate.connection.password A felhasználó jelszava. hibernate.dialect Az adatbázisunk dialektusa. Ez általában a hibernatehez jár, speciális DBMS-ekhez esetleg sajátot implementálnak. A hibernate doksiban megtalálhatók a lehetséges értékei. Pl.: org.hibernate.dialect.OracleDialect
  28. 28. hibernate.show_sql Ha értéke true , akkor munden DML művelet esetén mutatja a használt SQL utasítást. hibernate.order_updates Ha értéke true , akkor frissítéskor a sorokat elsődleges kulcs alapján rendezi. Ez csökkentheti a tranzakciók holtpontjait a nagyon terhelt rendszerekben. www.hibernate.org/hib_docs/v3/reference/en/html/session-configuration.html További konfigurációs részletek itt:
  29. 29. Amit láttatok, az a hibernatenek csak egy része – az alapok. Sok metódusnak sokkal több túlterhelése van, és van olyan, amit be sem mutattam. Ezekről, és a hibernate mélyebb működéséről a www.hibernate.org oldalon olvashattok bővebben. Ott nem az API-t érdemes nézegetni, mert elég „ritkás”. Inkább a hibernate wikivel foglalkozzatok. Sok sikert!
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×