AutomatisiertePersistenz: Persistenz

Werbung
AutomatisiertePersistenz:
Persistenz-Frameworks
Was ist Persistenz?
 Persistenz bedeutet, dass die Objekte die Programmausführung
überdauern
 Praktisch: Objekte werden in einer Datenbank "aufbewahrt"
 Auch Dateisystem möglich
 Nicht:
Die Objekte holen sich Ihre Infos aus einer Datenbank,
Sondern: Die Objekte werde aus der Datenbank geholt
 3-Schichten-Architektur:
Datenhaltungsschicht muss alle relevanten Objekte dauerhaft
abspeichern – so dass sie das Programmende überleben
 Außerdem können bei großen Anwendungen nicht alle Objekte
speicherresident sein
 Zwischenspeicherung in der DB.
(c) schmiedecke 08
SE2-4-Persistenzmodelle
2
OR-Mapping
 Abbildung vom Klassenmodell auf das Relationale Datenmodell.
 Systematische Zuordnung (OR-Mapping)
Bis auf Vererbung identisch mit der Abbildung ERMRelationales Modell
– Klasse
Tabelle oder Tabellengruppe
– Beziehung  Fremdschlüssel und ggf. Verknüpfungstabelle
– Vererbung  Tabelle oder Tabellengruppe
 Damit kann das Relationale Schema für die Persistenz automatisch
erzeugt werden.
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
3
Direkte Datenbank-Anbindung per JDBC
class ERM online shop
Produk t
-
Orde r
Produktnummer: int
Preis: double
Name: String
*
Info: String
AnzKolli: int
Gewicht: double
* -

Bestelldatum: Date
Lieferdatum: Date
Versandform: String
Rechnungsnummer: int
Bearbeiter: String
*
*
*
1
*
1
Kunde
Einkaufsw agen
-
Datum: Date
Kreditk arte
1
1 -
Name: String
Strasse: String 1
Ort: String
PLZ: int
JDBC
(c) schmiedecke 12
1.. *
-
Kartentyp: String
Kartennummer: int
Gültigkeit: Date
Beziehung zwischen Klassen
und Tabellen nicht erkennbar
 Regeln für den
"Zusammenbau" von Objekten
aus DB-Daten müssen explizit
programmiert werden

SE2-6-Persistenz-Frameworks
SQL-Verwendung:
Datenbank enthält Daten, nicht
Objekte, d.h. es kann nicht
direkt nach Objekten gesucht
werden
4
ORM
class ERM online shop
Produk t
-
Orde r
Produktnummer: int
Preis: double
Name: String
*
Info: String
AnzKolli: int
Gewicht: double
* -
Bestelldatum: Date
Lieferdatum: Date
Versandform: String
Rechnungsnummer: int
Bearbeiter: String
*
*
*
1
*
1
Kunde
Einkaufsw agen
-
Datum: Date
Kreditk arte
1
1 -
Name: String
Strasse: String 1
Ort: String
PLZ: int
ORM
(c) schmiedecke 12
1.. *
-
Kartentyp: String
Kartennummer: int
Gültigkeit: Date
 ORM liefert die
Abbildung
zwischen Klassen
und Tabellen (gruppen)
 Query Language
ermöglicht Suche
auf Objektebene
 Es gibt keine
DML, sondern
Objekte werden
manipuliert und
dann persistiert
SE2-6-Persistenz-Frameworks
5
OR-Mapping – auf dem Weg zum Traum
OR-Mapping
 Abbildungsschema zwischen
Objektmodell und Datenmodell

Entitytyp (~"Tablelle") und
Klasse sind verwandte Konzepte

Abbildung "einfacher Objekte",
d.h. von Objekten, die keine
weiteren Objekte enthalten /
referieren, ist trivial:
–
–

Klasse wird Tabelle
Attribute werden
Tabellenattribute
Komplexe Objekte und
Objektbeziehungen erfordern
komplexere Abbildung
(c) schmiedecke 08
SE2-4-Persistenzmodelle
6
ORM mit JPA
Bei Ausführung*
wird das DBSchema erzeugt

JPA = Java Persistence API
Bestandteil von EJB 3 – aber auch in JSA nutzbar.

Kennzeichnung der zu persistierenden Klassen durch Annotation
@Entity

Kennzeichnung der Beziehungen durch Annotationen
@OneToMany, @OneToOne, @ManyToOne, @ManyToMany

Kennzeichnung der Vererbungs-Strategie durch Annotationen
@Inheritance(strategy=…)

Spezifikation des DB-Zugangs in einer PersistenceUnit (persistence.xml)
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
*) Ausführung eines
DB-Zugriffs
7
Beispiel-Modell
von ArgoUML generierter Code:
public class Student
extends Unimitglied {
public int matrikelnummer;
public int semester;
/**
*
* @element-type Dozent
*/
public Vector myDozent;
public Dozent myDozent;
}
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
8
Von der Klasse zur Entity
von ArgoUML generierter Code:
komplettierter und annotierter Code:
public class Student
extends Unimitglied {
public int matrikelnummer;
public int semester;
/**
*
* @element-type Dozent
*/
public Vector myDozent;
public Dozent myDozent;
}
(c) schmiedecke 12
@Entity
public class Student
extends Unimitglied {
@Id
Integer id;
int matrikelnummer;
int semester;
@ManyToMany
Collection<Dozent> myDozent;
@ManyToOne
Dozent myTutor;
public
public
…
publíc
public
SE2-6-Persistenz-Frameworks
…
}
Integer getID() {…}
int getMatrikelnummer() {…}
void setId(Integer id) {…}
void setMatrikelnummer(…){…}
9
Automatisch erzeugtes DB-Schema
Das
Schema hängt von der SE2-6-Persistenz-Frameworks
gewählten Vererbungs-Strategie ab!
(c) schmiedecke 12
10
Entity-Annotation
@Entity
@Table(name="T_Student")
public class Student extend Unimitglied{
@Id @GeneratedValue int id;
public int getId() { return id; }
public void setId(int id) { this.id=id; }
…
}
 @Entity deklariert eine Klasse als persistent.
 Die Angabe des Tabellennamens ist optional
standardmäßig wird der Klassenname verwendet.
 Alle Attribute müssen als Properties gekapselt werden.
 Es muss eine numerische @Id – Property eingefügt werden,
 am besten mit generierten Werten.
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
11
Vererbungs-Annotation
@Entity
@Table(name="T_Mitglied")
@Inheritance(Strategy=Inheritance.JOINED
public class Unimitglied { ….}




Die Vererbungs-Strategie wird bei der Basisklasse annotiert
Standard ist SINGLE_TABLE
JOINED entspricht Einzeltabellen für alle Klassen der Hierarchie
Die Strategie TABLE_PER_CLASS (Tabelle je konkrete Klasse)
muss nicht auf allen Servern implementiert sein (Testen Sie
Glassfish daraufhin)
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
12
ORM: Attributspezifikation per Annotation
 @Basic
– Basisdatentyp
 @LOB
– BLOB oder CLOB nach Bedarf
 @Temporal
– Zeitwert
 @Embedded
– eigebettetes Objekt (strukturiertes Objekt mit 1:1-Beziehung)
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
13
Assoziations-Annotation
@ManyToMany
private Collection<Dozent> myDozent;
@ManyToOne
private Dozent myTutor;
@ManyToMany(mappedBy = "myDozent")
private Collection<Student> myStudent;






Annotation entweder immer der Attribute oder immer der Getter.
Annotation entsprechend den Kardinalitäten.
bei @XToMany sollte der Typ eine generische Collection sein (oder eine
Unterklasse von Collection).
Ersatzweise kann der Elementtyp als Attribut targetEntity="Dozent"
angegeben werden.
Bei bidirektionalen Assoziationen muss auf der zweiten Seite in einer
mappedBy-Angabe der Name des bezugnehmenden Attributs der ersten
Seite angegeben werden.
Bei @OneToOne kann das Attribut optional=false gesetzt werden
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
14
Kurzanleitung zum "Zaubern" (CRUD)
1. JSF-Projekt anlegen
2. Im SourcePackages-Verzeichnis ein Paket mit annotierten EntityKlassen erzeugen.
3. Eine PersistenceUnit anlegen (Netbeans fordert sie dazu auf –
wählen sie am besten eine leere DB)
4. Im Kontextmenü des Projekts
New >> JSF Pages from Entity Classes
wählen und die gewünschten Klassen selektieren
5. warten…
6. Projekt ausführen. Wenn sie mögen, tragen Sie Werte ein.
7. DB ansehen / bestaunen.
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
15
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
16
ORM ist noch nicht Persistenz

OR-Mapping:
– Wie werden Objekte auf Datenbanktupel abgebildet?
– Genauer: Wie wird das Klassenmodell auf das Datenbankschema abgebildet?

DB-Connection:
– Wie baut man die Verbindung zur richtigen Datenbank auf?

Objekt-Materialisierung, -Dematerialisierung und -Suche
– Wie werden aus Tupeln Objekte gebaut?
– Und welche referierten Tupel werden mit geladen?
– Und wie findet man die Objekte in der Datenbank?

Objekt-Caching und -Synchronisation:
– Wie werden Speicherobjekte und Datenbank synchron gehalten?
(c) schmiedecke 08
SE2-4-Persistenzmodelle
17
Persistenz mit JPA
 Java Persistence API
–
–
–
–
Persistenzmodell der EJB 3.0-Spezifikation
mehrere Implementierungen (Hibernate JPA, toplink, …)
Auf jedem JEE-Server vorhanden
Aber seit EJB 3.0 auch für POJOS (=Plain Old Java Objects),
d.h. ausgelagert aus JEE.
 Jede Java-Klasse kann "Persistent Entity" sein
– wenn sie "will"
 Java-5-Annotationen spezifizieren
–
–
–
–
Persistenz
ORM
Umgang mit Abhängigkeiten
Ladeverhalten
… soweit waren wir schon
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
18
Ein paar Vokabeln vorweg
 Persistence Provider
- die JPA-Implementierung
 Persistence Unit
- Realisierung einer DB-Anbindung
- konfiguriert in der persistence.xml
 Persistence Context
- die Speicherobjekte (der Cache)
 Entity-Manager
- verwendet die Persistence Unit
- realisiert (De-)Materialisierung
- setzt die Objektsuche um
- verwaltet den Cache
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
19
Entity-Manager
find
query
Applikation
Detached objects
Persistenz-Kontext
persist
remove
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
flush
merge
refresh
Entity
Manager
DB
20
Wie erhält man den EntityManager:
J2SE
 Referenz auf EntityManager kann durch eine Factory erzeugt werden.
 Der zugehörige Persistenz-Kontext gilt für die Lebensdauer des EntityManagers
(Extendend)
private EntityManager entityManager =
EntityManagerFactory.createEntityManager()
JEE
 Ein Persistenz-Kontext gilt (per default) für eine Transaktion.
 Referenz auf Entity-Manager wird "injiziert" (Dependency injection), d.h. von der
Umgebung (automatisch) gesetzt:
@PersistenceContext
private EntityManager entityManager;
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
21
Arbeiten im Persistenz-Kontext
CLIENT-Operation:
Dozent dozent1 = jpaHelper.create();
JPA-Umsetzung
Dozent obj = new Dozent();
entityManager.persist(obj); return obj;
dozent.setName("Schmiedecke");
jpaHelper.update(dozent);
entityManager.merge(dozent);
//Objekt aktualisieren
jpaHelper.refresh(dozent);
entityManager.refresh(dozent);
jpaHelper.detach(dozent);
entityMangager.remove(dozent);
jpaHelper.refresh(dozent);
entityManager.refresh(???); // detached, also unbekannt
Dozent d2 = jpaHelper.findByName("Sauer");
(c) schmiedecke 12
Query query = entityManager.createQuery
("SELECT d FROM dozent WHERE s.name="Sauer");
SE2-6-7-Architekturübersicht
22
return (Dozent) (query.getResultList().getRow(0));
Objektsuche:
Queries in JPA

EntityManager ermöglicht das Erstellen und Ausführen von Queries
– Statische "NamedQueries", als Entity-Annotationen definiert
– Dynamisch erzeugte Queries
– Flush-Modus: Vor jeder Query wird der Persistenz-Kontext synchronisiert

SQL-Abfragen – sog. "Native Queries"
–

werden als Strings an die DB weitergerichteher weniger sinnvoll, da das DB-Schema eigentlich
verborgen ist
JPQL – die Abfragesprache von JPA
– Selektionsabfragen
Nachbildung der SQL auf Objektebene – Weitergabe dennoch als Strings
– Aktualisierungs- und Löschanweisungen
(Nur selten sinnvoll, etwa Massenaktualisierungen; sollte besser auf der Ebene der Geschäftsobjekte erfolgen)

Criteria API
– programmatische Abfragen auf Objektebene in Java
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
23
JPQL



Grundsyntax der SELECT-Klauseln wie SQL:
SELECT, WHERE, AND, OR, ORDER BY etc
die üblichen arithmetischen, logischen und Vergleichsoperationen

die Variablen sind Pfadausdrücke im Klassenschema
– können über Klassengrenzen führen
"SELECT s.myTutor.fb FROM Student s"
 Parametrisierung
– nummerierte Parameter ?0, ?1, ?2
– Namensparameter :name, :vorname, :matrikel
– Setzen durch setParameter() auf einer Query
Query q = em.createQuery("SELECT … WHERE s = ?0");
q.setParameter(0, 1234);
List<String> liste = q.getResultList();
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
24
Named Queries


Vor der @Entity-Annotation kann eine Liste von benannten Abfragen stehen, die
sich auf dieKlasse beziehen.
JPQL- oder "native" (SQL) Abfragen
@NamedQuery(name="alleStudenten",
query="SELECT s FROM Student s")
@NamedNativeQuery(name="AlleStudentenNativ",
query="SELECT * FROM STUDENT")
@Entity
public class Student extends Unimitglied {…}

Verwendung mit createNamedQuery:
List<Student> liste =
em.createNamedQuery("alleStudentenNativ").getResultList();
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
25
Der Java-Weg: Criteria-Query
 Queries werden als Java-Objekte "gebaut"
Typsicher und Injection-sicher
 Idee ähnlich JDBC:
– CriteriaQuery-Objekt gehört zu einem EntityManager
– der CriteriaQuery werden schrittweise die Kriterien hinzugefügt
– die CriteriaQuery wird "abgeschickt" und liefert eine ResultList
oder ein SingleResult
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
26
Aufbau einer CriteriaQuery
public List<Student> findAll() {
EntityManager em = getEntityManager();
CriteriaQuery cq =
em.getCriteriaBuilder().createQuery();
cq.select(cq.from(Student.class));
Query q = em.createQuery(cq);
return q.getResultList();
}
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
27
Aufbau einer CriteriaQuery  SingleResult
public Long count() {
EntityManager em = getEntityManager();
CriteriaQuery cq =
em.getCriteriaBuilder().createQuery();
Root<Student> rt = cq.from(Student.class);
cq.select(em.getCriteriaBuilder().count(rt));
Query q = em.createQuery(cq);
return ((Long)q.getSingleResult()).intValue();
}
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
28
Klauseln einer CriteriaQuery
Quelle: http://www.ibm.com/developerworks/java/library/j-typesafejpa/
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
29
Transaktionen – Zurückschreiben in die DB
 Es gibt viele Möglichkeiten in JPA, Transaktionen
explizit oder implizit zu nutzen.
 Hier nur die einfachsten und gebräuchlichsten,
 JSE
– Schließen des EntityManagers (em.close()) beendet den
PersistenceContext und damit die aktuelle Transaktion
 JEE
– Wenn der EntityManager injiziert wurde, stellt automatisch der
Aufruf einer Bean-Methode eine Transaktion dar.
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
30
Transaktionen hinter den Kulissen
- der Objekte-Cache
 Sammelbecken für materialisierte Objekte
 Dematerialiserung bei
– Transaktionsende
– Speicherbedarf
– expliziter Speicherung oder Synchronisation
 Transaktionszustände der Cache-Objekte
– Es gibt materialisierte und neu erzeugte Objekte
– Objekte können im Cache verändert oder gelöscht werden
 6 Transaktionszustände:
new clean, old clean
new dirty,
old dirty
new deleted, old deleted
– pro Transaktionszustand ein Cachebereich
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
31
Dematerialisierung bedeutet Synchronisation
new clean  old clean
neu erzeugte (nicht materialisierte) Objekte, die nicht verändert wurden
→ Objekt in die Datenbank einfügen (insert)
old clean  old clean
alte materialisierte Objekte, die nicht verändert wurden
→ keine Aktion notwendig
new dirty  old clean
neu erzeugte (nicht materialisierte) Objekte, die verändert wurden
→ Objekt in die Datenbank einfügen (insert)
old dirty  old clean
alte materialisierte Objekte, die verändert wurden
→ Objekt in der Datenbank aktualisieren (update)
new deleted  X
neu erzeugte (nicht materialisierte) Objekte, die gelöscht wurden
→ Objekt aus dem Cache löschen
old deleted  X
alte materialisierte Objekte, die gelöscht wurden
schmiedecke 12
SE2-6-Persistenz-Frameworks
→(c)Objekt
aus der Datenbank löschen
(delete)
32
Synchronisation (bei Transaktionsende)
new clean
old clean
new dirty
old dirty
new deleted
old deleted
 Cache-Aktionen abhängig von Transaktionszuständen
 Zustände können automatisch verwaltet.werden.
(c) schmiedecke 12
SE2-6-7-Architekturübersicht
33
Persistenzkonzepte behandelt

OR-Mapping:
– Wie werden Objekte auf Datenbanktupel abgebildet?
– Genauer: Wie wird das Klassenmodell auf das Datenbankschema abgebildet?

DB-Connection:
– Wie baut man die Verbindung zur richtigen Datenbank auf?

Objekt-Materialisierung, -Dematerialisierung und -Suche
– Wie werden aus Tupeln Objekte gebaut?
– Und welche referierten Tupel werden mit geladen?
– Und wie findet man die Objekte in der Datenbank?

Objekt-Caching und -Synchronisation:
– Wie werden Speicherobjekte und Datenbank synchron gehalten?
(c) schmiedecke 08
SE2-4-Persistenzmodelle
34
Fazit: Persistenz ist machbar!
 saubere Strukturen
 klare Regeln
 aber mühsam!
 Persistenz-Frameworks nehmen uns die Arbeit ab!
– Persistenz ohne Programmierleistung
– Minimaler Konfigurationsaufwand
– Und ein leicht zu verstehendes Konzept
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
35
Der Traum: Transparente Persistenz

Animation unter
http://www.servicearchitecture.com/object-relationalmapping/articles/transparent_persi
stence.html

Abfolge
–
–
–
–
–
–
–
–
–
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
Application will Person
benutzen
Cache ist leer
Mapping holt Persontupel aus der DB
Person wird im Cache
aufgebaut
Zugriffsversuch auf
Adresse
fehlt im Cache
Bezug aus der DB
Update Adresse
Rückschreiben in die DB
36
Wer materialisiert die Objekte?
Direkte und indirekte Persistenz
 Direkte Persistenz:
– jedes persistente Objekt enthält Methoden, um sich selbst zu
materialisieren / dematerialisieren / synchronisieren.
– Wissen über den DB-Zugang und den entsprechenden Teil des
Datenmodells sind in jeder Klasse vorhanden.
– DB-Zugang, Datenmodell und Persistenzstrategie schwer
änderbar.
 Indirekte Persistenz
– den Fachobjekten sind Persistierungsobjekte sind zugeordnet
– Materialisierung / Dematerialisierung / Synchronisation erfolgt "von
außen" als Service für die Fachobjekte.
– Voraussetzung für transparente Persistenz.
(c) schmiedecke 08
SE2-4-Persistenzmodelle
37
Transparente Persistenz
 Ziel ist eine transparente Persistenz
– Die Anwendung soll mit Objekten arbeiten
– und möglichst wenig von der Persistenz merken
 Das bedeutet kapseln:
– Zugriffswissen kapseln
 DAO-Muster
– Zugriffs - und Klassenwissen trennen  Broker-Muster
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
38
DAO – Data Access Objects
(Persistierungsobjekte)

Annahme aus der Analysephase:
–
–
–
–

Klasse verwaltet die Menge ihrer Objekte
würde jetzt bedeuten, dass jede Klasse die DB-Details kennt
nicht transparent
DB-Wechsel sehr aufwändig
Data Access Object – der Objekte-Baumeister:
– Klassenspezifisches Zugriffsobjekt
– kapselt die DB-Details
– liefert und persistiert die
Anwendungsobjekte

Nachteile
 Für jede Klasse ein DAO
 Viel redundanter Code
 Viel Aufwand bei DB-Wechsel
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
39
Das Broker-Muster
• kennt und verwaltet den Objekt-Cache
• benutzt getObject(oid, class)
• Methode getObject(oid, class) ist abstract
• kennt die DB
• kann den passenden Objektbroker ermitteln
• Methode getObject(oid, class) ist Schablone,
benutzt getObject(oid)
• Methode getObject(oid) ist abstract
• kennt und verwaltet den Objekt-Cache
• Methode getObject ist implementiert
(c) schmiedecke 12
Der Klassenspezifische DAO-Anteil
ist klein und DB-neutral:
SE2-6-Persistenz-Frameworks
40
Generische Lösung
Einfachere Umsetzung mit
generischen Klassen:
AbstractDAO <Type>
getObject(int id):<Type>
ORMManager
StudentDAO
getObject(int id):Student
(c) schmiedecke 12
 Die Klasse AbstractDAO enthält
getObject als generische
Schablonenmethode
 Die Verbindungsinformation und der
DB-Zugriff wird als separates Objekt
eingebunden
 In der Konkretisierung wird der
tatsächliche Typ eingesetzt
SE2-6-Persistenz-Frameworks
41
OR-Mapping – Lazy Materialization
 Laden externer Objekte:
– Was ist mit den assoziierten Objekten?
– Objektstruktur kann stark verzweigen...
 Proxy-Entwurfsmuster:
–
–
–
–
Objekt erreichbar über ein Stellvertreterobjekt (Proxy)
Proxy liegt im Speicher
besorgt das Nachladen des Objekts bei Bedarf
enthält das OID
(c) schmiedecke 08
SE2-4-Persistenzmodelle
42
Proxy-Entwurfsmuster

Objektassoziation des Client verweist auf einen Platzhalter
– Proxy,
– imitiert Struktur des realen Subjekts.

Anfrage (request) erzeugt Bedarf:
– Das reale Subjekt wird geladen
– und die Anfrage delegiert.
(c) schmiedecke 08
SE2-4-Persistenzmodelle
43
DAO mit Proxy- und Broker-Muster
class Slides
Dozent
Stundenplan
+ getAdresse() : Adress


DozentReal
DozentProxy
+ getAdresse() : Address
+ getAdresse() : Address
DbBroker
DerbyBroker
DozentDAO
+ getObject(int) : Object
+ getObject(int) : Object
+ getObject(int) : Object
erst bei Bedarf wird Dozent als DozentReal mithilfe des DAO materialisiert
der gesamte Persistenzapparat bleibt unter der Oberfläche.
(c) schmiedecke 12
SE2-6-7-Architekturübersicht
44
Fazit
 Persistenz-Frameworks liefern den sicheren Umgang
mit persistierten Objekten.
 Ziel: POJO-Architektur
Die Schnittstelle zur Persistenz wird aus den
Fachobjekten ausgelagert  DAOs.
Fachobjekte sind POJOS
 Alternativer Ansatz: "Active Record"
Jedes Fachobjekt erweitert eine Persistierungsklasse.
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
45
Alternative OO-DB-Persistenz
 ORM entfällt 
 Persistenzkonzepte, Caching und Synchronisation
bleiben.
 Probieren Sie z.B. db4o, Sie werden staunen, wie leicht
das ist!
(www.db4o.com)
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
46
Die wichtigsten Java-Persistenzframeworks
 Hibernate
– Der Klassiker (~2002) Gavin King & Team
– Bekannt als ORM-Framework
– Konzept- und Begriffsbilder (Persistenz, Entity, …)
 JDO - Java Data Objects
– Spezifikation, einige Referenz-Implementierungen
– Vereinfachte Persistenz von POJOS
– D.h. persistente Objekte müssen nichts implementieren
 JPA – Java Persistence API
– Modernstes Konzept, Spezifikation
– Bestandteil von JEE (EJB 3.0) – aber herauslösbar
– Ebenfalls POJO-Persistenz
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
47
Weitere Java-ORM-Frameworks (open source)










Ibatis SQL Maps
OJB
Torque
Castor
Cayenne
TJDO
JDBM
Prevayler
JPOX
Speedo








Jaxor
pBeans
SimpleORM
Smyle
XORM
O/R Broker
Mr.Persister
Java Ultra Light
Persistence
 JDBCPersistence
 Ammentos
 Velosurf











PAT
daozero
QLOR
ODAL
JPersist
BeanKeeper
Open JPA
Super CSV
SeQuaLite
Persist
...
http://java-source.net/open-source/persistence
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
48
Versprochen,
das war's in Sachen Persistenz!
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
49
Anhang:
Annotations-Details
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
50
ORM: Beziehungsspezifikation per Annotation
Unidirektionale 1:1-Beziehung
Kunde
Agentur
0..1
0..1
@Entity
public class Kunde {
private int id;
private Agentur agentur;
...
@OneToOne
@JoinColumn(name="AGENTUR-ID")
public Agentur getAgentur() { return agentur; }
}
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
51
ORM: Beziehungsspezifikation per Annotation
Bidirektionale 1:1-Beziehung
Kunde
Agentur
0..1
0..1
@Entity
@Entity
public class Kunde {
public class Agentur {
private int id;
private int id;
private Agentur agentur;
private Kunde kunde;
...
...
@OneToOne
@OneToOne(mappedBy="agentur")
@JoinColumn(name="AGENTUR-ID")
public Agentur getKunde()
public Agentur getAgentur()
{ return kunde; }
{ return agentur; }
}
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
52
}
ORM: Beziehungsspezifikation per Annotation
Unidirektionale 1:N-Beziehung
Agentur
0..1
*
Kunde
@Entity
public class Agentur {
private int id;
private Collection<Kunde> kunden;
...
@OneToMany(cascade=CascadeType.ALL)
public Collection<Kunde> getKunden()
{ return kunden; }
....
}
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
@Entity
public class Kunde {
private int id;
...
}
53
ORM: Beziehungsspezifikation per Annotation
Bidirektionale 1:N-Beziehung
Agentur
0..1
*
Kunde
@Entity
@Entity
public class Kunde {
public class Agentur {
private int id;
private int id;
private Agentur agentur;
private Collection<Kunde> kunden;
...
...
@ManyToOne
@OneToMany(cascade=CascadeType.ALL
@JoinColumn(name="AGENTUR_ID
mappedBy="agentur")
public Agentur getAgentur()
public Collection<Kunde> getKunden()
{ return agentur; }
{ return kunden; }
}
....
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
54
}
ORM: Beziehungsspezifikation per Annotation
Bidirektionale M:N-Beziehung
@Entity
*
*
Agentur
Kunde
public class Agentur {
private int id;
private Collection<Kunde> kunden;
@Entity
...
public class Kunde {
@ManyToMany
private int id;
@JoinTable(name="AGENTUR_KUNDE",
private Collection<Agentur>
joinColumns=
agenturen;
@JoinColumn(name="AGENTUR_ID",
...
referencedColumnName="ID"),
@ManyToMany (mappedBy=kunden)
inverseJoinColumns=
@JoinColumn(name="KUNDE_ID",
public Collection<Agentur>
referencedColumnName="ID") )
getAgenturen()
public Collection<Kunde> getKunden()
{ return agenturen; }
{ return kunden; }
}
....(c) schmiedecke
}
12
SE2-6-Persistenz-Frameworks
55
ORM: Vererbungsabbildung per Annotation
InheritanceType
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TYP",
discriminatorType=CHAR)
@DiscriminatorValue("K")
public abstrct class Kunde {
private int id;
....
}
@Entity
@DiscriminatorValue("P")
public abstrct class Privatkunde extends
Kunde {
...
}
(c) schmiedecke 12
Kunde
Privatkunde
Firmenkunde
@Entity
@DiscriminatorValue("F")
public abstrct class Fimenkunde extends
Kunde {
...
}
SE2-6-Persistenz-Frameworks
56
Persistenz:
Kaskadierungspezifikation per Annotation
@Entity
public class Agentur {
private int id;
private Collection<Kunde> kunden;
...
@OneToMany(cascade= {
CascadeType.PERSIST, CascadeType.MERGE,
CascadeType.REFRESH, CascadeType.REMOVE }
mappedBy="agentur")
public Collection<Kunde> getKunden()
{ return kunden; }
....
}
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
57
Persistenz:
Nachladestrategie per Annotation
@Entity
public class Agentur {
private int id;
private Collection<Kunde> kunden;
...
@OneToMany(cascade= CascadeType.ALL,
fetchType=FetchType.LAZY,
mappedBy="agentur")
public Collection<Kunde> getKunden()
{ return kunden; }
....
}
(c) schmiedecke 12
SE2-6-Persistenz-Frameworks
58
Herunterladen