SlideShare ist ein Scribd-Unternehmen logo
1 von 29
Downloaden Sie, um offline zu lesen
Tajti Ákos http://cesjava.freeblog.hu
[object Object],[object Object],[object Object],[object Object],A lényeg: A hibernate elrejti előlünk a fizikai adatbázist
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; … } ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
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>
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.
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ó).
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(); …
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)).
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ó).
… 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));
Egy perzisztens osztály (ami le van képezve adatbázisra) három állapotban  lehet (egyszerre persze csak egyben): ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],Tranziens Perzistens Detached új gc
//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.
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.
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.
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.
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.
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 ).
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.
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.
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){ } }
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!
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 } }
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){ } }
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();
//ú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 
A hibernate konfigurációjához három helyen szólhatunk hozzá: ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],propertynév=valami -> <property name=”propertynév”>valami</property> ,[object Object],[object Object]
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
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:
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!

Weitere ähnliche Inhalte

Hibernate tutorial

  • 2.
  • 3.
  • 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. 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. 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. 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. 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. 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. … 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.
  • 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. //ú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.
  • 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. 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. 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!