3. Perzisztencia

A VIK Wikiből
(OotPerzisztencia szócikkből átirányítva)

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

ObjectInput interfész

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.