Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

21
Object Relational Mapping (ORM)

Transcript of Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

Page 1: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

Object Relational Mapping

(ORM)

Page 2: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

Objektmodell - Datenbankmodell

Page 3: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

ORM

• Pro Datenbanktabelle eine Klasse im Objektmodell (Data Transfer Object; DTO)

• Pro Datensatz in der Tabelle eine Instanz der Klasse

• Eigene Klassen für die Datenbankzugriffe (Data Access Object; DAO)

Page 4: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

ORM

cd_id cd_interpret cd_titel

1 Robbie W. Best of

2 Madonna Greatest …

… … …

Page 5: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

Schattendaten

id (Primärschlüssel)lastUpdate (optimistic locking)storedInDb (bereits als Datensatz vorhanden)

Page 6: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

Data Access Object (DAO)

• Verschiedene Methoden für das Auswählen

• Speichern

• Löschen

Page 7: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

findByPrimaryKey()SELECT cd_interpret, cd_titel

FROM CDSWHERE cd_id = ?

ResultSet rs = …if (rs.next()){

CD cd = new CD();cd.setId(id);cd.setTitel(rs.getString("cd_titel"));cd.setInterpret(rs.getString("cd_interpret"));return cd;

}else

return null;

Page 8: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

findAll()SELECT cd_id, cd_interpret, cd_titel

FROM CDS

List<CD> liste = new ArrayList<CD>();ResultSet rs = …while (rs.next()){

CD cd = new CD();cd.setId(rs.getInt("cd_id"));cd.setTitel(rs.getString("cd_titel"));cd.setInterpret(rs.getString("cd_interpret"));liste.add(cd);

}…return liste;

Page 9: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

findByTitle()SELECT cd_id, cd_interpret, cd_titel

FROM CDSWHERE cd_titel = ?

List<CD> liste = new ArrayList<CD>();ResultSet rs = …while (rs.next()){

CD cd = new CD();cd.setId(rs.getInt("cd_id"));cd.setTitel(rs.getString("cd_titel"));cd.setInterpret(rs.getString("cd_interpret"));liste.add(cd);

}…return liste;

Page 10: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

save(CD cd)

if (cd.isStoredInDb()){

// UPDATE...

}else{

// INSERT...

}

PreparedStatement pstmt = …

if (pstmt.executeUpdate() == 1){

// ok}else{

// Fehler}

INSERT INTO CDS (cd_id, cd_interpret, cd_titel)VALUES (?, ?, ?)

UPDATE CDS SET cd_interpret = ?, cd_titel = ?WHERE cd_id = ?

Page 11: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

remove()

DELETE FROM CDSWHERE cd_id = ?

PreparedStatement pstmt = …

if (pstmt.executeUpdate() == 1){

// ok}else{

// Fehler}

Page 12: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

Einige wichtige Regeln

• Parametrierte (?) Statements verwenden

• Einzelne Spalten mit Namen ansprechen (kein „SELECT * …“)

• Update-Count überprüfen

• Datenbankverbindung wiederverwenden

• ResultSet und PreparedStatement schließen

Page 13: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

INSERT und Primary Key

cd_id cd_interpret cd_titel

1 Robbie W. Best of

2 Madonna Greatest …

… … …INSERT

Page 14: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

ResultSet keys = pstmt.getGeneratedKeys();if (keys.next())

cd.setId(keys.getInt(1));

INSERT und Primary Key

• getGeneratedKeys()

• Sequenzen

Page 15: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

DTO Caching

Beispiel:dao.findByPrimaryKey(key) liefert eine Referenz auf die CD-Instanz mit dem übergebenen Primärschlüssel.

Problem: Bei mehreren Aufrufen mit dem selben key sollte immer die selbe Instanz geliefert werden.

Lösung:DAO muss einen Cache von bereits aus Datenbank ausgelesenen Instanzen halten (z.B Map<Key,DTO>)

Page 16: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

Inkonsistenzen bei Fehlerfällen

Beispiel:Überweisung eines Betrages von einem Bankkonto auf ein anderes.Saldo wird beim ersten Konto um den Betrag reduziert. Bevor der Saldo beim zweiten Konto entsprechend erhöht wird, stürzt das Programm ab. Inkonsistenz

Lösung:Verwenden einer Transaktion

Page 17: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

Datenbank-Transaktion

In JDBC hängt die Transaktion an der Datenbankverbindung (Connection):•con.setAutoCommit(false);•con.commit(); •con.rollback();Jedes commit() oder rollback() beginnt zugleich die nächste Transaktion.

Savepoints:•Savepoint sp = con.setSavepoint();•con.rollback(sp);

Page 18: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

Gleichzeitige Zugriffe

Problem:2 Clients bearbeiten den selben Datensatz.• Beide Clients holen den Datensatz aus der Datenbank• Client 1 ist fertig mit der Bearbeitung und führt ein Update

durch.• Client 2 ist fertig mit der Bearbeitung und führt ein Update

durch. Die Änderungen von Client 1 gehen verloren.

Lösung:Datensatz muss beim Auslesen aus der Datenbank

gesperrt werden. Datenbank-spezifisch: SELECT ... FOR UPDATE; LOCK TABLE ...

Page 19: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

Pessimistic Locking

• Datensatz wird ausgelesen und gesperrt.• Datensatz wird bearbeitet.• Update wird durchgeführt.• Datensatz wird freigegeben.

Nachteil:Datensatz sehr lange gesperrt, wenn

Programm abstürzt, etc.

Page 20: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

Optimistic locking

• Datensatz wird ausgelesen aber nicht gesperrt.• Datensatz wird bearbeitet.• Datensatz wird noch einmal ausgelesen und

diesmal gesperrt.• Falls Datensatz noch gleich ist wie beim ersten

Auslesen Update und Freigabe• Falls Datensatz inzwischen verändert wurde,

müssen Änderungen verworfen oder zusammengeführt werden.

Page 21: Object Relational Mapping (ORM). Objektmodell - Datenbankmodell.

Update-Timestamp

Jede Tabelle erhält ein zusätzliches Timestamp-Feld (last_upd). Darin wird Zeitpunkt des letzten Updates gespeichert.•Datensatz wird ausgelesen•Datensatz wird bearbeitet•Update:

UPDATE … WHERE last_upd = …

Wenn zwischendurch kein Update von anderem Client erfolgt ist, ist Update-Count = 1, ansonsten 0.