3. Perzisztencia
A VIK Wikiből
Ez az oldal a korábbi SCH wikiről lett áthozva.
Ha úgy érzed, hogy bármilyen formázási vagy tartalmi probléma van vele, akkor, kérlek, javíts rajta egy rövid szerkesztéssel!
Ha nem tudod, hogyan indulj el, olvasd el a migrálási útmutatót.
3.1. 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
- kiírás/beolvasás felüldefiniálása
- writeExternal(ObjectOutput out)
- readExternal(ObjectInput in)
%ATTACHURL%/srl-osztalydiagram.png
3.2. 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át is kezel
- referencia más osztályokra
- lásd reláció (1:1, 1:n, 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â\x{fffd}\x{fffd} 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:
- tranziens - még nem kapcsolódótt
- perzisztens - adatbázistáblával összekötve
- 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
- Contrainteket is kezel
3.3. PSEPro (ObjectStore)
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 - memóriában módosított
- 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)
%ATTACHURL%/os-tranzakciok.png
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(); FreeVariableBindings fvb = new FreeVariableBindings(); fv.put("IS", Integer.TYPE); fvb.put("IS", new Integer(20000)); Query q = new Query(Person.class, "getSalary()>=IS", fv); Collection employees = (Collection)db.getRoot("employees"); Set result1 = q.select(employees); // több eredmény Object result2 = q.pick(employees); // 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.