„3. Perzisztencia (2012)” változatai közötti eltérés
Ugrás a navigációhoz
Ugrás a kereséshez
a (autoedit v2: fájlhivatkozások egységesítése, az új közvetlenül az adott fájlra mutat) |
|||
(9 közbenső módosítás, amit 6 másik szerkesztő végzett, nincs mutatva) | |||
1. sor: | 1. sor: | ||
− | + | {{RightTOC}} | |
==Szerializálás== | ==Szerializálás== | ||
===Serializable interfész=== | ===Serializable interfész=== | ||
10. sor: | 10. sor: | ||
* Leszármazottak szerializálás-lánca megszakítható a read/writeObject-ben NotSerializableException dobásával | * Leszármazottak szerializálás-lánca megszakítható a read/writeObject-ben NotSerializableException dobásával | ||
===Kimentés=== | ===Kimentés=== | ||
− | < | + | <syntaxhighlight lang="java"> |
class SerializableClass implements java.io.Serializable | class SerializableClass implements java.io.Serializable | ||
22. sor: | 22. sor: | ||
... | ... | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
===Visszaállítás=== | ===Visszaállítás=== | ||
− | < | + | <syntaxhighlight lang="java"> |
try { | try { | ||
FileInputStream f = new FileInputStream("filename"); | FileInputStream f = new FileInputStream("filename"); | ||
33. sor: | 33. sor: | ||
catch(IOException ex) { ... } | catch(IOException ex) { ... } | ||
catch(ClassNotFoundException ex) { ... } | catch(ClassNotFoundException ex) { ... } | ||
− | </ | + | </syntaxhighlight> |
===ObjectOutput interfész=== | ===ObjectOutput interfész=== | ||
* mindenre throws IOException | * mindenre throws IOException | ||
52. sor: | 52. sor: | ||
* http://download.oracle.com/javase/1.4.2/docs/api/java/io/ObjectInput.html | * http://download.oracle.com/javase/1.4.2/docs/api/java/io/ObjectInput.html | ||
===Externalizable interfész=== | ===Externalizable interfész=== | ||
+ | * csak az osztály azonosítása mentődik automatikusan, a többi a mi kezünkben | ||
* kiírás/beolvasás felüldefiniálása | * kiírás/beolvasás felüldefiniálása | ||
* writeExternal(ObjectOutput out) | * writeExternal(ObjectOutput out) | ||
* readExternal(ObjectInput in) | * readExternal(ObjectInput in) | ||
− | [[ | + | [[File:srl-osztalydiagram.png]] |
==Hibernate 3.0== | ==Hibernate 3.0== | ||
68. sor: | 69. sor: | ||
* <property> attribútum -> oszlop | * <property> attribútum -> oszlop | ||
* <many-to-one>, <one-to-one>, reláció | * <many-to-one>, <one-to-one>, reláció | ||
− | < | + | <syntaxhighlight lang="xml"> |
<hibernate-mapping> | <hibernate-mapping> | ||
<class name="auto.Person" table="PERSON"> | <class name="auto.Person" table="PERSON"> | ||
88. sor: | 89. sor: | ||
</class> | </class> | ||
</hibernate-mapping> | </hibernate-mapping> | ||
− | </ | + | </syntaxhighlight> |
===Kollekciók=== | ===Kollekciók=== | ||
* <set>, <list>, <map>, <bag>, <array>, <<p>-array> | * <set>, <list>, <map>, <bag>, <array>, <<p>-array> | ||
* Javaban a megfelelő Collection interfészt kell használni, nem castolható | * Javaban a megfelelő Collection interfészt kell használni, nem castolható | ||
− | < | + | <syntaxhighlight lang="xml"> |
<class name="Product"> | <class name="Product"> | ||
<id name="serialNumber" column="SN"/> | <id name="serialNumber" column="SN"/> | ||
100. sor: | 101. sor: | ||
</set> | </set> | ||
</class> | </class> | ||
− | </ | + | </syntaxhighlight> |
===Asszociáció=== | ===Asszociáció=== | ||
− | * | + | * kapcsolótáblával (join table) vagy anélkül |
* referencia más osztályokra | * referencia más osztályokra | ||
− | * lásd reláció (1:1, 1:n, n:m) | + | * lásd reláció (1:1, 1:n, n:1, n:m) |
===Öröklés=== | ===Öröklés=== | ||
* Támogatott: | * Támogatott: | ||
** table-per-class-hierarchy (minden egy táblában, discriminator: típusjelölő) | ** table-per-class-hierarchy (minden egy táblában, discriminator: típusjelölő) | ||
− | < | + | <syntaxhighlight lang="xml"> |
<class ...> | <class ...> | ||
− | <discriminator column=" | + | <discriminator column="PAYMENT_TYPE" type="string"/> |
<subclass name="CredCPay" discriminator-value="CREDIT"> | <subclass name="CredCPay" discriminator-value="CREDIT"> | ||
<property name="credCType" column="CCTYPE"/> | <property name="credCType" column="CCTYPE"/> | ||
116. sor: | 117. sor: | ||
</subclass> | </subclass> | ||
</class> | </class> | ||
− | </ | + | </syntaxhighlight> |
** table-per-subclass | ** table-per-subclass | ||
− | < | + | <syntaxhighlight lang="xml"> |
<class ...> | <class ...> | ||
<joined-subclass name="CredCPayment" table="CREDIT_PAYMENT"> | <joined-subclass name="CredCPayment" table="CREDIT_PAYMENT"> | ||
126. sor: | 127. sor: | ||
</joined-subclass> | </joined-subclass> | ||
</class> | </class> | ||
− | </ | + | </syntaxhighlight> |
** table-per-concrete-class | ** table-per-concrete-class | ||
− | < | + | <syntaxhighlight lang="xml"> |
<class ...> | <class ...> | ||
<union-subclass name="CredCPayment" table="CREDIT_PAYMENT"> | <union-subclass name="CredCPayment" table="CREDIT_PAYMENT"> | ||
135. sor: | 136. sor: | ||
</union-subclass> | </union-subclass> | ||
</class> | </class> | ||
− | </ | + | </syntaxhighlight> |
+ | |||
===Objektumok kezelése=== | ===Objektumok kezelése=== | ||
− | * Állapotok: | + | * Állapotok (Session-höz képest): |
** tranziens - még nem kapcsolódótt | ** tranziens - még nem kapcsolódótt | ||
** perzisztens - adatbázistáblával összekötve | ** perzisztens - adatbázistáblával összekötve | ||
− | ** detached - már nem kapcsolódik | + | ** lekapcsolt (detached) - már nem kapcsolódik |
* Műveletek: | * Műveletek: | ||
** session.flush() - módosítások mentése | ** session.flush() - módosítások mentése | ||
153. sor: | 155. sor: | ||
* Query q = session.createQuery(…); | * Query q = session.createQuery(…); | ||
* visszatérés: skalár vagy tömb | * visszatérés: skalár vagy tömb | ||
− | < | + | <syntaxhighlight lang="java"> |
X x = (X)session.createQuery(..).uniqueResult(); | X x = (X)session.createQuery(..).uniqueResult(); | ||
List l = session.createQuery(..).list(); | List l = session.createQuery(..).list(); | ||
Iterator i = session.createQuery(..).iterate(); | Iterator i = session.createQuery(..).iterate(); | ||
− | </ | + | </syntaxhighlight> |
* paraméterek: név (:xname) vagy sorszám (? ? ?) | * paraméterek: név (:xname) vagy sorszám (? ? ?) | ||
− | < | + | <syntaxhighlight lang="java"> |
q.setString("x", "param"); | q.setString("x", "param"); | ||
q.setString(1, "param1"); | q.setString(1, "param1"); | ||
− | </ | + | </syntaxhighlight> |
===HQL=== | ===HQL=== | ||
* From | * From | ||
170. sor: | 172. sor: | ||
* Where | * Where | ||
* Order by, Group by | * Order by, Group by | ||
− | * | + | * Constrainteket is kezel |
+ | |||
+ | ==JPA (Java Persistance API)== | ||
+ | === Alapok === | ||
+ | * entitások: POJO (Plain olda java object) - szerializálhatónak kell lennie (más nem is kell) | ||
+ | * szabványos O-R kapcsolat | ||
+ | * lekérdezhetöség | ||
+ | * Entity Manager (EM) a felügyelö | ||
+ | ** Persistence context (PC): perzisztens objektumok futási környezete, élettartamár a konténer vagy az alkalmazás menedzseli | ||
+ | * Session (hibernate) == EM (JPA) ?? | ||
+ | * Persistence Unit: standard könyvtárszerkezet, O-R leképezéseket, relációkat, ezek hatásközét tartalmazza, illetve Java annotációkat és/vagy XML-t (persistence.xml) | ||
+ | |||
+ | === Entitás === | ||
+ | * @Entity annotáció (vagy XML) | ||
+ | * public vagy protected argumentum nélküli konstruktora van (final kizárva: osztály, metódus, változó) | ||
+ | * Serializable-t implementálja | ||
+ | * örökölhet entitástól vagy POJO-tól, POJO örökölhet entitástól | ||
+ | * konténeren kívül is használhatóak | ||
+ | [[File:oo_jpa_entitas.png]] | ||
+ | |||
+ | ==== Perzisztens elemek ==== | ||
+ | * mezötöl és propertytöl is függ hogy perzisztens-e | ||
+ | * nem szerializálható elemek: static, transient, @Transient | ||
+ | * szerializálhatóak: mezök és propertyk (@Basic): primitiv, string, wrapper, byte[], char[], enum, Collection, Set, List, Map (generic is), összetett, beágyazott (@Embedded) | ||
+ | * betöltés lehet: Eager és Lazy | ||
+ | |||
+ | ==== Kulcs ==== | ||
+ | * Primary key kötelezö | ||
+ | * egyszerü kulcs: @Id, ami lehet primitiv, wrapper, string, date | ||
+ | * összetett kulcs | ||
+ | ** Primary Key osztály: @IdClass | ||
+ | ** Kulcs elem: @EmbeddedId | ||
+ | * kulcsgenerálás: @GeneratedValue(strategy = GenerationType.X), ahol X = AUTO, SEQUENCE, IDENTITY, TABLE | ||
+ | |||
+ | ==== Entitások életciklusa ==== | ||
+ | * Entity Manager müveletei: persist, refresh, remove, merge | ||
+ | * Entity Manager egyéb müveletei: find, getReference, flush, clear, Query | ||
+ | * tranzitivitas: reláció paramétere, cascase = (müveletek) + ALL | ||
+ | <syntaxhighlight lang="java"> | ||
+ | @Entity | ||
+ | public class MyClass implements Serializable { | ||
+ | @Basic | ||
+ | Date birthday; | ||
+ | } | ||
+ | |||
+ | |||
+ | <entity name="mydonain.MyClass"> | ||
+ | <attributes> | ||
+ | <basic name="birthday"/> | ||
+ | </attributes> | ||
+ | </entity> | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === Relációk === | ||
+ | * megegyezik a Hibernate-tel | ||
+ | * Annotációs: @OneToOne, @OneToMany, @ManyToOne, @ManyToMany | ||
+ | * egy- és kétirányú, kétirányúnál tulajdonos oldal - idegen kulcs, inverz oldal - referencia (mappedBy = ) | ||
+ | <syntaxhighlight lang="java"> | ||
+ | @Entity | ||
+ | public class Car implements Serializable { | ||
+ | @ManyToOne | ||
+ | private Person owner; | ||
+ | |||
+ | |||
+ | @Entity | ||
+ | public class Person implements Serializable { | ||
+ | @OneToMany(mappedBy = "owner") | ||
+ | private Collection<Car> cars = new HastSet(); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==== Öröklés ==== | ||
+ | * table-per-class-hierarchy, table-per-subclass, table-per-concrete-class | ||
+ | |||
+ | === Lekérdezések === | ||
+ | * JPQL (Java Persistence Query Language) | ||
+ | * Statikus lekérdezések: @NamedQuery, @NamedNativeQuery | ||
+ | <syntaxhighlight lang="java"> | ||
+ | @Entity | ||
+ | @NamedQuery(name = "carByPlate", query = "SELECT c FROM Car c WHERE c.plate = :rsz") | ||
+ | |||
+ | |||
+ | Car c = (Car) em.createNamedQuery("carByPlate").setParameter("rsz", plate).getSingleResult(); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | * Dinamikus lekérdezések: runtime string komponálás, paraméterezéssel | ||
+ | <syntaxhighlight lang="java"> | ||
+ | Query query = em.createQuery("SELECT p FROM Product p WHERE p.param2 < :threshold ORDER BY p.param1 ascending"); | ||
+ | query.setParamater("threshold", my_threshold); | ||
+ | |||
+ | List results = query.getResultList(); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | * Natív SQL lekérdés a konkrét DB nyelve szerint, számozott paraméterezéssel | ||
+ | <syntaxhighlight lang="java"> | ||
+ | Query query = em.createNativeQuery("SELECT * FROM Product p WHERE p.param2 < ?1"); | ||
+ | query.setParameter(1, my_threshold).setMaxResults(10); | ||
+ | List results = query.getResultList(); | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | * Criteria Query (Hibernate), Builder minta szerint futás közben | ||
+ | <syntaxhighlight lang="java"> | ||
+ | CriteriaQuery cq1 = em.getCriteriaBuilder().createQuery(); | ||
+ | cq1.select(cg1.from(Person.class)); | ||
+ | |||
+ | Iterator iter = ((List<Person>) em.createQuery(cq1).getResultList()).iterator(); | ||
+ | </syntaxhighlight> | ||
==PSEPro (ObjectStore)== | ==PSEPro (ObjectStore)== | ||
+ | * OO adatbázis, 50 MB adatkezelés, egy-felhasználós, konkurens session-ök, alkalmazáson belül fut, nincs külsö adatbázis, szemétgyüjtés megoldva | ||
===Objektumok tulajdonságai=== | ===Objektumok tulajdonságai=== | ||
* Állapotok: | * Állapotok: | ||
** hollow (üres) - egy üres objektum, amibe az adatbázisból késleltetetten betölthetőek az adatok | ** hollow (üres) - egy üres objektum, amibe az adatbázisból késleltetetten betölthetőek az adatok | ||
− | ** aktív - adatbázisban kapcsolatban áll | + | ** aktív - adatbázisban kapcsolatban áll (clean/dirty) |
− | |||
** stale (lejárt) - adatbázishoz nem kapcsolt | ** stale (lejárt) - adatbázishoz nem kapcsolt | ||
+ | |||
===Szálak és Sessionök=== | ===Szálak és Sessionök=== | ||
* egyidőben egy adatbázishoz kapcsolódhat | * egyidőben egy adatbázishoz kapcsolódhat | ||
185. sor: | 293. sor: | ||
* session public static Session create(String host, Properties props) | * session public static Session create(String host, Properties props) | ||
* session létrehozása és törlése | * session létrehozása és törlése | ||
− | < | + | <syntaxhighlight lang="java"> |
public static Session create(String host, Properties props) | public static Session create(String host, Properties props) | ||
public boolean isActive() | public boolean isActive() | ||
public void terminate() | public void terminate() | ||
− | </ | + | </syntaxhighlight> |
* szálak kapcsolódása és lecsatolása | * szálak kapcsolódása és lecsatolása | ||
− | < | + | <syntaxhighlight lang="java"> |
public void join() | public void join() | ||
public static void leave() | public static void leave() | ||
− | </ | + | </syntaxhighlight> |
===Adatbázisok=== | ===Adatbázisok=== | ||
* adatbázis létrehozás, megnyitás, bezárás | * adatbázis létrehozás, megnyitás, bezárás | ||
− | < | + | <syntaxhighlight lang="java"> |
public static Database create(String name, int fileMod) | public static Database create(String name, int fileMod) | ||
public static Database open(String name, int openMode) | public static Database open(String name, int openMode) | ||
public void close(boolean RetainAsTransient) | public void close(boolean RetainAsTransient) | ||
− | </ | + | </syntaxhighlight> |
===Tranzakciók=== | ===Tranzakciók=== | ||
* egyszerre egy sessionhöz kapcsolódhat | * egyszerre egy sessionhöz kapcsolódhat | ||
* kiadhat read-lockot és update-lockot is | * kiadhat read-lockot és update-lockot is | ||
− | < | + | <syntaxhighlight lang="java"> |
public static Transaction begin(int type) | public static Transaction begin(int type) | ||
public void commit(int retain) | public void commit(int retain) | ||
public void abort(int retain) | public void abort(int retain) | ||
− | </ | + | </syntaxhighlight> |
− | [[ | + | [[File:os-tranzakciok.png]] |
===Objektumok=== | ===Objektumok=== | ||
* perzisztenciához az objektumok root-tá tesszük | * perzisztenciához az objektumok root-tá tesszük | ||
− | < | + | <syntaxhighlight lang="java"> |
db.createRoot("foo", new Integer(5)); | db.createRoot("foo", new Integer(5)); | ||
int x = (int)db.getRoot("foo"); | int x = (int)db.getRoot("foo"); | ||
db.setRoot("foo", null); | db.setRoot("foo", null); | ||
db.destroyRoot("foo"); | db.destroyRoot("foo"); | ||
− | </ | + | </syntaxhighlight> |
* minden kollekciónak megvan a maga OS... megfelelője | * minden kollekciónak megvan a maga OS... megfelelője | ||
===Query=== | ===Query=== | ||
* paraméteres lekérdezés (fv opcionális) | * paraméteres lekérdezés (fv opcionális) | ||
− | < | + | <syntaxhighlight lang="java"> |
FreeVariables fv = new FreeVariables(); | FreeVariables fv = new FreeVariables(); | ||
− | |||
fv.put("IS", Integer.TYPE); | fv.put("IS", Integer.TYPE); | ||
− | + | Query q = new Query(Person.class, "getSalary()>=IS", fv); | |
− | |||
Collection employees = (Collection)db.getRoot("employees"); | Collection employees = (Collection)db.getRoot("employees"); | ||
− | Set result1 = q.select(employees); // több eredmény | + | FreeVariableBindings fvb = new FreeVariableBindings(); |
− | Object result2 = q.pick(employees); // egyetlen eredmény | + | fvb.put("IS", new Integer(20000)); |
+ | Set result1 = q.select(employees, fvb); // több eredmény | ||
+ | Object result2 = q.pick(employees, fvb); // egyetlen eredmény | ||
+ | </syntaxhighlight> | ||
− | |||
===Példa=== | ===Példa=== | ||
− | < | + | <syntaxhighlight lang="java"> |
private String dbName = "cardb.odb"; | private String dbName = "cardb.odb"; | ||
private Session session; | private Session session; | ||
261. sor: | 369. sor: | ||
tr.commit(ObjectStore.RETAIN_HOLLOW); | tr.commit(ObjectStore.RETAIN_HOLLOW); | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
-- [[MeszegetoBalazsIstvan|MeszegetoBalazsIstvan]] - 2008.05.27. | -- [[MeszegetoBalazsIstvan|MeszegetoBalazsIstvan]] - 2008.05.27. |
A lap jelenlegi, 2017. július 12., 14:14-kori változata
Szerializálás
Serializable interfész
- csak az szerializálódik, ami meg van vele jelölve
- formális
- tömbök szerializálódnak
- Object, Thread, Socket, nem szerializálódnak
- transient és static cuccok nem szerializálódnak
- a private static final %ObjectStreamField[] serialPersistentFields tömbben megjelölt cuccok szerializálódnak
- Leszármazottak szerializálás-lánca megszakítható a read/writeObject-ben NotSerializableException dobásával
Kimentés
class SerializableClass implements java.io.Serializable
try {
FileOutputStream f = new FileOutputStream("filename");
ObjectOutputStream out = new ObjectOutputStream(f);
out.writeObject(_SerializableClass);
out.close();
}
catch(IOException ex) {
...
}
Visszaállítás
try {
FileInputStream f = new FileInputStream("filename");
ObjectInputStream in = new ObjectInputStream(f);
o_ins = (SerializableClass)in.readObject();
in.close();
}
catch(IOException ex) { ... }
catch(ClassNotFoundException ex) { ... }
ObjectOutput interfész
- mindenre throws IOException
- writeObject(Object obj)
- write(int b)
- write(byte b[])
- write(byte b[], int off, int len)
- flush()
- close()
- http://download.oracle.com/javase/1.4.2/docs/api/java/io/ObjectOutput.html
ObjectInput interfész
- throws ClassNotFoundException, IOException
- Object readObject()
- read...()
- public long skip(long n)
- public int available()
- public void close()
- http://download.oracle.com/javase/1.4.2/docs/api/java/io/ObjectInput.html
Externalizable interfész
- csak az osztály azonosítása mentődik automatikusan, a többi a mi kezünkben
- kiírás/beolvasás felüldefiniálása
- writeExternal(ObjectOutput out)
- readExternal(ObjectInput in)
Hiba a bélyegkép létrehozásakor: Nem lehet a bélyegképet a célhelyre menteni
Hibernate 3.0
Alkalmazás átalakítása
- ID attribútumok (jól jöhet)
- konfigurációs fájl (xml)
- HSQL DB indítás
Leképezés
- <hibernate-mapping> gyökérelem
- <class> perzisztens osztály -> tábla
- <id>, <generator> azonosító, generátor algoritmus (pl native)
- <property> attribútum -> oszlop
- <many-to-one>, <one-to-one>, reláció
<hibernate-mapping>
<class name="auto.Person" table="PERSON">
<id name="id" column="PERSON_ID">
<generator class="native"/>
</id>
<property name="name"/>
<set name="cars" inverse="true" cascade="persist">
<key column="PERSON_ID" not-null="true"/>
<one-to-many class="auto.Car"/>
</set>
</class>
<class name="auto.Car" table="CAR">
<id name="id" column="CAR_ID">
<generator class="native"/>
</id>
<property name="platenr"/>
<many-to-one name="owner" class="auto.Person" column="PERSON_ID" not-null="true" cascade="persist"/>
</class>
</hibernate-mapping>
Kollekciók
- <set>, <list>, <map>, <bag>, <array>, <<p>-array>
- Javaban a megfelelő Collection interfészt kell használni, nem castolható
<class name="Product">
<id name="serialNumber" column="SN"/>
<set name="parts">
<key column="SN" not-null="true"/>
<one-to-many class="Part"/>
</set>
</class>
Asszociáció
- kapcsolótáblával (join table) vagy anélkül
- referencia más osztályokra
- lásd reláció (1:1, 1:n, n:1, n:m)
Öröklés
- Támogatott:
- table-per-class-hierarchy (minden egy táblában, discriminator: típusjelölő)
<class ...>
<discriminator column="PAYMENT_TYPE" type="string"/>
<subclass name="CredCPay" discriminator-value="CREDIT">
<property name="credCType" column="CCTYPE"/>
...
</subclass>
</class>
- table-per-subclass
<class ...>
<joined-subclass name="CredCPayment" table="CREDIT_PAYMENT">
<key column="PAYMENT_ID"/>
<property name="credCType" column="CCTYPE"/>
...
</joined-subclass>
</class>
- table-per-concrete-class
<class ...>
<union-subclass name="CredCPayment" table="CREDIT_PAYMENT">
<property name="credCType" column="CCTYPE"/>
...
</union-subclass>
</class>
Objektumok kezelése
- Állapotok (Session-höz képest):
- tranziens - még nem kapcsolódótt
- perzisztens - adatbázistáblával összekötve
- lekapcsolt (detached) - már nem kapcsolódik
- Műveletek:
- session.flush() - módosítások mentése
- session.update(x) - újrakapcsolódás DB-hez, mentés
- session.saveOrUpdate(x) - elmenti az objektumot. Ha az id property-je null, akkor SQL INSERT utasítást hajt végre, ha not null, akkor SQL UPDATE utasítást hajt végre
- session.merge(x) - DB-ben és memóriában lévő cuccok összefésülése
- session.delete(x) - törlés
Tranzakciók
- csak így érhető el a DB
- Session osztály
Lekérdezések
- Query q = session.createQuery(…);
- visszatérés: skalár vagy tömb
X x = (X)session.createQuery(..).uniqueResult();
List l = session.createQuery(..).list();
Iterator i = session.createQuery(..).iterate();
- paraméterek: név (:xname) vagy sorszám (? ? ?)
q.setString("x", "param");
q.setString(1, "param1");
HQL
- From
- Join (inner, left outer, right outer, full outer)
- Select
- Aggregáló funkciók (avg(), sum(), min(), max(), count())
- Where
- Order by, Group by
- Constrainteket is kezel
JPA (Java Persistance API)
Alapok
- entitások: POJO (Plain olda java object) - szerializálhatónak kell lennie (más nem is kell)
- szabványos O-R kapcsolat
- lekérdezhetöség
- Entity Manager (EM) a felügyelö
- Persistence context (PC): perzisztens objektumok futási környezete, élettartamár a konténer vagy az alkalmazás menedzseli
- Session (hibernate) == EM (JPA) ??
- Persistence Unit: standard könyvtárszerkezet, O-R leképezéseket, relációkat, ezek hatásközét tartalmazza, illetve Java annotációkat és/vagy XML-t (persistence.xml)
Entitás
- @Entity annotáció (vagy XML)
- public vagy protected argumentum nélküli konstruktora van (final kizárva: osztály, metódus, változó)
- Serializable-t implementálja
- örökölhet entitástól vagy POJO-tól, POJO örökölhet entitástól
- konténeren kívül is használhatóak
Hiba a bélyegkép létrehozásakor: Nem lehet a bélyegképet a célhelyre menteni
Perzisztens elemek
- mezötöl és propertytöl is függ hogy perzisztens-e
- nem szerializálható elemek: static, transient, @Transient
- szerializálhatóak: mezök és propertyk (@Basic): primitiv, string, wrapper, byte[], char[], enum, Collection, Set, List, Map (generic is), összetett, beágyazott (@Embedded)
- betöltés lehet: Eager és Lazy
Kulcs
- Primary key kötelezö
- egyszerü kulcs: @Id, ami lehet primitiv, wrapper, string, date
- összetett kulcs
- Primary Key osztály: @IdClass
- Kulcs elem: @EmbeddedId
- kulcsgenerálás: @GeneratedValue(strategy = GenerationType.X), ahol X = AUTO, SEQUENCE, IDENTITY, TABLE
Entitások életciklusa
- Entity Manager müveletei: persist, refresh, remove, merge
- Entity Manager egyéb müveletei: find, getReference, flush, clear, Query
- tranzitivitas: reláció paramétere, cascase = (müveletek) + ALL
@Entity
public class MyClass implements Serializable {
@Basic
Date birthday;
}
<entity name="mydonain.MyClass">
<attributes>
<basic name="birthday"/>
</attributes>
</entity>
Relációk
- megegyezik a Hibernate-tel
- Annotációs: @OneToOne, @OneToMany, @ManyToOne, @ManyToMany
- egy- és kétirányú, kétirányúnál tulajdonos oldal - idegen kulcs, inverz oldal - referencia (mappedBy = )
@Entity
public class Car implements Serializable {
@ManyToOne
private Person owner;
@Entity
public class Person implements Serializable {
@OneToMany(mappedBy = "owner")
private Collection<Car> cars = new HastSet();
Öröklés
- table-per-class-hierarchy, table-per-subclass, table-per-concrete-class
Lekérdezések
- JPQL (Java Persistence Query Language)
- Statikus lekérdezések: @NamedQuery, @NamedNativeQuery
@Entity
@NamedQuery(name = "carByPlate", query = "SELECT c FROM Car c WHERE c.plate = :rsz")
Car c = (Car) em.createNamedQuery("carByPlate").setParameter("rsz", plate).getSingleResult();
- Dinamikus lekérdezések: runtime string komponálás, paraméterezéssel
Query query = em.createQuery("SELECT p FROM Product p WHERE p.param2 < :threshold ORDER BY p.param1 ascending");
query.setParamater("threshold", my_threshold);
List results = query.getResultList();
- Natív SQL lekérdés a konkrét DB nyelve szerint, számozott paraméterezéssel
Query query = em.createNativeQuery("SELECT * FROM Product p WHERE p.param2 < ?1");
query.setParameter(1, my_threshold).setMaxResults(10);
List results = query.getResultList();
- Criteria Query (Hibernate), Builder minta szerint futás közben
CriteriaQuery cq1 = em.getCriteriaBuilder().createQuery();
cq1.select(cg1.from(Person.class));
Iterator iter = ((List<Person>) em.createQuery(cq1).getResultList()).iterator();
PSEPro (ObjectStore)
- OO adatbázis, 50 MB adatkezelés, egy-felhasználós, konkurens session-ök, alkalmazáson belül fut, nincs külsö adatbázis, szemétgyüjtés megoldva
Objektumok tulajdonságai
- Állapotok:
- hollow (üres) - egy üres objektum, amibe az adatbázisból késleltetetten betölthetőek az adatok
- aktív - adatbázisban kapcsolatban áll (clean/dirty)
- stale (lejárt) - adatbázishoz nem kapcsolt
Szálak és Sessionök
- egyidőben egy adatbázishoz kapcsolódhat
- tetszőleges read-only tranzakciója lehet
- egyetlen update tranzakciója lehet
- session public static Session create(String host, Properties props)
- session létrehozása és törlése
public static Session create(String host, Properties props)
public boolean isActive()
public void terminate()
- szálak kapcsolódása és lecsatolása
public void join()
public static void leave()
Adatbázisok
- adatbázis létrehozás, megnyitás, bezárás
public static Database create(String name, int fileMod)
public static Database open(String name, int openMode)
public void close(boolean RetainAsTransient)
Tranzakciók
- egyszerre egy sessionhöz kapcsolódhat
- kiadhat read-lockot és update-lockot is
public static Transaction begin(int type)
public void commit(int retain)
public void abort(int retain)
Hiba a bélyegkép létrehozásakor: Nem lehet a bélyegképet a célhelyre menteni
Objektumok
- perzisztenciához az objektumok root-tá tesszük
db.createRoot("foo", new Integer(5));
int x = (int)db.getRoot("foo");
db.setRoot("foo", null);
db.destroyRoot("foo");
- minden kollekciónak megvan a maga OS... megfelelője
Query
- paraméteres lekérdezés (fv opcionális)
FreeVariables fv = new FreeVariables();
fv.put("IS", Integer.TYPE);
Query q = new Query(Person.class, "getSalary()>=IS", fv);
Collection employees = (Collection)db.getRoot("employees");
FreeVariableBindings fvb = new FreeVariableBindings();
fvb.put("IS", new Integer(20000));
Set result1 = q.select(employees, fvb); // több eredmény
Object result2 = q.pick(employees, fvb); // egyetlen eredmény
Példa
private String dbName = "cardb.odb";
private Session session;
private Database db;
private Set carOwners;
public void initDB() {
session = Session.create(null, null);
session.join();
try {
db = Database.open(dbName, ObjectStore.UPDATE);
}
catch (DatabaseNotFoundException e) {
db = Database.create(dbName, ObjectStore.ALL_READ | ObjectStore.ALL_WRITE);
}
Transaction tr = Transaction.begin(ObjectStore.UPDATE);
try {
carOwners = (Set)db.getRoot("OwnersRoot");
}
catch (DatabaseRootNotFoundException ex) {
carOwners = new OSHashSet();
db.createRoot("OwnersRoot", carOwners);
}
tr.commit(ObjectStore.RETAIN_HOLLOW);
}
-- MeszegetoBalazsIstvan - 2008.05.27.
-- Velias - 2009.05.26.
-- Vad Zsolt - 2011.04.07.