Document

Werbung
Persistenzframeworks
Präsentation im Rahmen des
Software Engineering-Seminars
Zaferna-Hütte, 5. Januar 2009
Georg Senft
Inhalt
Grundbegriffe
Objektrelationales
Mapping
LINQ
Hibernate
und JPA
Einordnung
Heraus
Herausforderungen
Architektur
Exkurs: Spracherweiterungen
Lösungen
objektrelationales
Mapping
Abfragen
LINQ
to SQL
• ORM
• Abfragen
2
NHibernate
Fazit
Grundbegriffe
Framework
konzeptspezifische Lösung für generisches Problem
OO: insb. Vererbung, →White-Box-Wiederverwendung
Problem-Abdeckung ~ Standardisierbarkeit
Persistenz
Fähigkeit einer Anwendung, Daten in einem nicht-flüchtigen
Speicher zu sichern und später wiederherzustellen.
Persistenzframework
allgemein: Lösung für weit verbreitete Persistenz-Anforderung
dabei: Kapselung → Entkoppelung
+ speziell
DBMS): Objektrelationales
i ll (OO & relationales
l ti
l DBMS)
Obj kt l ti
l Mapping
M
i
3
Objektrelationales Mapping (1/5)
Abbild
Abbildung:
objektorientierte
bj kt i ti t ↔ relationale
l ti
l Strukturen
St kt
Problem: Verschiedenheit der Paradigmen
objektorientiertes Paradigma
Pendant
relationales Paradigma
Kl
Klasse
T b ll (R
Tabelle
(Relation)
l ti )
Attribut
Attribut
Objekt
Datensatz (Tupel)
Assoziation
Assoziation
Liste
Primärschlüssel
Vererbung
Methoden
„Impedanz-Unterschied“
4
Objektrelationales Mapping (2/5)
Mapping:
Klasse ↔ Tabelle
einfache
e
ac e Attribute
bu e ↔ Attribute
bu e
Objektinstanzen ↔ Datensätze
objektorientiert
j
relational
Klasse
Tabelle (Relation)
Attribut
Attribut
Objekt
Datensatz (Tupel)
Herausforderung: Primitive Typen ↔ SQL-Datentypen
SQL Datentypen
Java, C#, VB.NET
byte
short
float
char
int
double
übliche SQL-Typen
long
decimal
String/string
real
smallint
double
char(n)
int
bigint
decimal(n,m)
varchar(n)
boolean/bool
bit
(GregorianCalendar/DateTime)
date time timestamp datetime
Längenangaben
herstellerindividuelle Datentypen
zusätzlich: NULL-Wert
5
tinyint
blob(n)
( )
clob(n)
( )
Objektrelationales Mapping (3/5)
objektorientiert
j
relational
Assoziation
Assoziation
1:1-Beziehung und n:1-Beziehung:
Automobil
1
*
Person
Halter►
1
Automobil
ID … Halter
Strategien
zur Primärschlüssel-Vergabe:
g
g
Generierung durch DBMS
V
Verwendung
d
von P
Pseudo-Zufallszahlen
d Z f ll
hl
etc.
6
Primärschlüssel
Person
ID
…
Objektrelationales Mapping (4/5)
1:n-Beziehung:
Automobil
Fahrer: Person[]
*
relational
Assoziation
Assoziation
Liste
Person
0 1
0..1
objektorientiert
j
*
Automobil
ID
…
Person
ID …
Auto
m:n-Beziehung:
m:n
Beziehung:
Automobil
Automobil
Person
Fahrer: Person[] Autos:Automobil[]
*
7
*
ID
…
AutoPersZuo
ID AID PID
Person
ID
…
Objektrelationales Mapping (4/5)
1:n-Beziehung:
Automobil
Fahrer: Person[]
*
relational
Assoziation
Assoziation
Liste
Person
0 1
0..1
objektorientiert
j
*
Automobil
ID
…
Person
ID …
Auto
OO: keine Unterscheidung
Automobil
Automobil
Fahrer: Person[]
8
Person
*
*
ID
…
AutoPersZuo
ID AID PID
Person
ID
…
Vererbung: 3 Strategien
Kfz
Leistung
Pkw
Türen
Objektrelationales Mapping (5/5)
relational
Klasse
Tabelle
Lkw
Achsen
Tabelle je Klasse
vollständige
Tabelle je Klasse
Kfz
ID Diskriminator Leistg
Leistg.
Kfz
ID Diskriminator
Pkw
ID Türen
Pkw
ID Leistungg Türen
Lkw
ID Achsen
Lkw
ID Leistung Achsen
Vorteil: effiziente Speichernutzung
9
objektorientiert
j
Vererbung
gemeinsame Tabelle
Kfz
ID Diskr
Diskr. Leistung Türen Achsen
bei großer Klassenvielfalt
LINQ für .NET
L
Language
Integrated
I t
t d Query
Q
für
fü Microsoft
Mi
ft .NET
NET 3.5
35
vereinheitlichte Syntax für Arbeit mit Datenmengen und Elemente
erweiterbarer
Umfang
an LINQ-Providern
it b
U
f
LINQ P id
Sprachintegration, neuartige Sprachelemente
Programmiersprachen
C#
LINQ‐Bausteine
Expression‐Bäume
LINQ‐Provider
LINQ to Objects
Visual Basic
Abfrage‐Ausdrücke
Abfrage‐Operationen
LINQ to SQL
LINQ to XML
SQL Server
XML
LINQ to Entities
KlasseA
KlasseB
int : Zahl
KlasseB : myB
Datenquellen
foo()
bar()
int : ZahlB
bool : fertig
flexnet()
indapta()
Objekte
10
Entity Framework
Exkurs: Spracherweiterungen in C# 3.0 (1/1)
Objekt-Initialisierer
Kurzschreibweise für Initialisierung + Setzen öffentlicher Attribute
Cl o = new Cl(4) { Attr1 = 1, Attr2 = 2 };
Erweiterungsmethoden
Bestehende Klassen ohne Vererbung
g um Methoden erweitern
internal static void add(this int a,int b){ a+=b; }
Implizit typisierte Variablen
lokales var innerhalb einer Methode, Initialisierung erforderlich
Anonyme Typen
var mit Objektinitialisierer für implizite
implizite, neue Klasse
Lambda-Ausdrücke
vergleichbar mit anonymen Methoden,
Typen
Methoden Delegat
Delegat-Typen
Array.FindAll<int>(Zahlen, i => (i<42) );
vom Compiler in Expression-Baum übertragen
11
LINQ to SQL (1/5)
ORM für bestehende SQL Server Datenquellen
grafisches ORM-Werkzeug in Visual Studio liefert gemappte Klassen
Verwendung von Annotationen,
Annotationen sog.
sog „Attributen
Attributen“
an gemappte Klasse[Table(Name="dbo.Automobil")]
[Column(DbType="DateTime NOT NULL",CanBeNull=false)]
[Column(DbType="DateTime")]
System.Nullable<System.DateTime> Erstzulassung
Primärschlüssel: IsPrimaryKey=true und IsDbGenerated=…
Assoziation: [Association(ThisKey="Halter",
OtherKey="PersonID", IsForeignKey=true)]
Person PersonHalter;
Gegenseite: EntitySet<Automobil> AutosGehalten;
neben den gemappten Klassen:
DataContext für DB-Interaktion getTable(), submitChanges()
typisierte Table als Grundlage für Abfragen
12
13
LINQ to SQL (2/5)
Abfrage:
anonym typisiert
t i i t als
l
vergleichbar:
l i hb
H k ft M
Herkunfts-Menge
IQueryable<Auto>
foreach
Table<Auto>
Operation
O
ti
(Auswahl)
var Autos = from auto in tabAutos select auto;
mit Kriterium und implizitem JOIN:
var Autos = from auto in tabAutos
where auto.PersonHalter.Vorname=="Georg"
select auto;
wird zum SQL-Ausdruck:
0
0
SELECT [t0].[Kennzeichen],
[t0].[Typ],
[t0].[Erstzulassung], [t0].[Halter]
FROM [dbo].[Automobil] AS [t0] LEFT OUTER JOIN
[dbo].[Person]
[t1].[PersonID]=[t0].[Halter]
[db ] [P
] AS [t1] ON [t1]
[P
ID] [t0] [H lt ]
WHERE [t1].[Vorname] = 'Georg'
14
LINQ to SQL (3/5)
Einfügen: tabAutos.InsertOnSubmit(neuesAuto);
ausgeführter SQL-Ausdruck:
INSERT INTO [dbo].[Automobil]
([Kennzeichen], [Typ], [Erstzulassung], [Halter])
VALUES (@p0, @p1, @p2, @p3)
SELECT CONVERT(Int,SCOPE_IDENTITY()) AS [value]
Löschen: tabAutos.DeleteOnSubmit(altesAuto);
Aktualisierungen implizit, danach
DataContext.submitChanges();
15
LINQ to SQL (4/5)
Prinzip des IQueryable für Abfragen:
Übersetzung des LINQ-Ausdrucks zu Expression-Baum
durch CIL-Compiler
Auswertung durch LINQ-Provider
Generierung und Ausführung adäquater SQL
SQL-Ausdrücke
Ausdrücke
C#
Expression‐Bäume
Abfrage‐Ausdrücke
LINQ to SQL
SQL Server
16
Abfrage‐Operationen
LINQ to SQL (5/5)
Transaktionen: explizit
über DataContext.Connection.BeginTransaction(..)
und anschließender Zuweisung an Kontext
Connection Pooling: implizit
über ADO.NET-Verbindung
g
bedarfsweises Laden der Tabellen (Lazy Fetching)
Normalfall, über DataLoadOptions regulierbar
Zwischenfazit LINQ
Q to SQL
Q und LINQ:
Q
vollständige Kapselung vorhandener MS SQL Sever-Datenquellen
Sprachintegration: Typsicherheit, Überprüfung, Vervollständigung
LINQ
Ausdrücke prägnant,
LINQ-Ausdrücke
prägnant zumindest bei geringer Komplexität
keine Zerlegung eines LINQ-Ausdrucks beim Debugging
17
Hibernate und Java Persistence API (1/4)
Java Persistence API (JPA)
Schnittstellenspezifikation für Persistenzframeworks (JSR 220)
Bestandteil von EJB 3.0, Bestandteil von Java EE 5.0
Einsatz in Java EE-Container oder Java SE 5.0-Anwendung
Hibernate
Open Source Persistenzframework, implementiert JPA, derzeit: 3.3.1
für JDBC-kompatible, relationale Datenquellen
Hibernate Funktionsumfang übersteigt JPA-Anforderungen
B t dt il
Bestandteile:
Entity Manager: JPA-kompatible Schnittstelle
pp g
p
g g
Core: zentrale OR-Mapping-Komponente
und Abfragegenerator
Annotations: ORM-Spezifikation per Annotationen in Java-Klassen
(alternativ: ORM-Spezifikation per XML-Datei)
18
Hibernate und Java Persistence API (2/4)
A
Annotationen
t ti
zur ORM-Spezifikation:
ORM S
ifik ti
Klassen erhalten @Entity
Primärschlüssel-Attribut
Primärschlüssel Attribut erhält @Id
ggf.: @GeneratedValue(Strategy=GenerationType…)
IDENTITY
TABLE
SEQUENCE
uuid
Generierung
g durch Datenbank
aktuelle Werte liegen in Sondertabelle
Generierung durch Sequenz in Datenbank (z. B. Oracle)
Pseudo-Zufallswert
Pseudo Zufallswert
weitere Attribute erhalten @Column ggf. mit nullable, length
Assoziationen:
@OneToOne mit @JoinColumn(name="…")
@OneToMany(mappedBy="…") an Set-Kollektion z. B. HashSet
und bei der Gegenseite @ManyToOne @JoinColumn(…)
@JoinColumn( )
@ManyToMany(…) mit Aktualisierungs-Operation
zusätzlich fetch=… und cascade=… möglich
19
Hibernate und Java Persistence API (3/4)
weitere Annotationen zur ORM-Spezifikation:
ORM Spezifikation:
Vererbung: @Entity zu @InheritanceStrategy(strategy=…)
TABLE_PER_CLASS
JOINED
SINGLE_TABLE
vollständige Tabelle je Klasse
Tabelle je Klasse (mit individuellen Attributen)
gemeinsame Tabelle, @DiscriminatorColumn
Verwendung des EntityManager
Erzeugung aus Session
y
j
p
für Entity-Objekte
persist()und remove()
Transaktionssteuerung
Suche anhand Primärschlüssel: find()
weiterführende Abfragen
EM.createNativeQuery()direkter SQL-Befehl an das DBMS
EM createQuery()
EM.createQuery()
JPA Query Language
Criteria
typsichere Parameter-Struktur
Example
Beispielobjekt als Kriterium
20
Hibernate und Java Persistence API (4/4)
weitere
it
Aspekte:
A
kt
Connection Pooling nur über Zusatz-Lösungen (z. B. C3PO)
E t ll
Erstellung
gemappter
t Tabellen
T b ll iin DBMS möglich,
ö li h
über: hb2ddl.SchemaExport.create()
diverse Werkzeuge
g für automatisierten Schema-Import
p und -Export
p
Zwischenfazit Hibernate / JPA:
vollständige Kapselung der Persistenz-Mechanismen
typsichere Verfahren zur Abfrage wie Criteria oder Example
automatisierte Tabellen-Generierung möglich
21
NHibernate für .NET
Portierung Hibernate → .NET
ausgehend von Version 2.1, seitdem eigenständig weiterentwickelt
Funktionsumfang NHibernate 2 vergleichbar mit Hibernate 3
kompatibel mit .NET ab 1.1
Datenzugriff per ADO.NET
somit auch OLE DB und ODBC
ORM-Spezifikation nur mit XML-Mapping-Dateien
Q to NHibernate-Provier
Version 3: LINQ
IQueryable wird über Criteria realisiert
22
Fazit
Grad der Problemabdeckung:
Objektrelationales Mapping gleichwertig umgesetzt
Kapselung der Datenzugriffsschicht gleichwertig umgesetzt
aber: LINQ to SQL nur für vorhandene Datenbanken
Abfragemechanismen:
JPA sehr allgemein
ausgereifte Mechanismen in Hibernate
Mechanismen in LINQ durch Sprachintegration prägnanter
Architekturvergleich: JPA ↔ LINQ
g der Sprache
p
g
→ LINQ durch Einbezug
umfasender und überlegen
23
Literatur
[MEW08] Fabrice
F b i Marguerie,
M
i Steve
St
Eichert,
Ei h t Jim
Ji Wooley:
W l
LINQ im
i Einsatz,
Ei
t Carl
C l Hanser
H
Verlag,
V l
2008.
2008
[Me08] Vijay P. Mehta: Pro LINQ Object Relational Mapping with C# 2008, Apress, 2008.
[PR07] Paolo Pialorsi, Marco Russo: Introducing Microsoft LINQ, Microsoft Press, 2007.
[Ra07] Joseph C. Rattz: Pro LINQ: Language Integrated Query in C# 2008, Apress, 2007.
[BHRS07] Robert F. Beeger, Arno Haase, Stefan Roock, Sebastian Sanitz: Hibernate – Persistenz in
Java-Systemen mit Hibernate und der Java Persistence API, 2. Aufl., dpunkt.verlag, 2007.
[He07] Sebastian Hennebrüder: Hibernate – Das Praxisbuch für Entwickler, Galileo Press, 2007.
[MW08] Bernd Müller, Harald Wehr: Java-Persistence-API mit Hibernate, Standardisierte Persistenz,
Addison-Wesley, 2008.
24
Herunterladen