1 / 21

Object Relational Mapping

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). ORM. Schattendaten.

dacey-buck
Télécharger la présentation

Object Relational Mapping

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Object Relational Mapping (ORM)

  2. Objektmodell - Datenbankmodell

  3. 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)

  4. ORM

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

  6. Data Access Object (DAO) • Verschiedene Methoden für das Auswählen • Speichern • Löschen

  7. findByPrimaryKey() SELECT cd_interpret, cd_titel FROM CDS WHERE 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 returnnull;

  8. 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;

  9. findByTitle() SELECT cd_id, cd_interpret, cd_titel FROM CDS WHERE 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;

  10. save(CD cd) INSERTINTO CDS (cd_id, cd_interpret, cd_titel) VALUES (?, ?, ?) UPDATE CDS SET cd_interpret = ?, cd_titel = ? WHERE cd_id = ? if (cd.isStoredInDb()) { // UPDATE ... } else { // INSERT ... } PreparedStatement pstmt = … if (pstmt.executeUpdate() == 1) { // ok } else { // Fehler }

  11. remove() DELETEFROM CDS WHERE cd_id = ? PreparedStatement pstmt = … if (pstmt.executeUpdate() == 1) { // ok } else { // Fehler }

  12. Einige wichtige Regeln • Parametrierte (?) Statements verwenden • Einzelne Spalten mit Namen ansprechen (kein „SELECT * …“) • Update-Count überprüfen • Datenbankverbindung wiederverwenden • ResultSet und PreparedStatement schließen

  13. INSERT und Primary Key INSERT

  14. INSERT und Primary Key • getGeneratedKeys() ResultSet keys = pstmt.getGeneratedKeys(); if (keys.next()) cd.setId(keys.getInt(1)); • Sequenzen

  15. 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>)

  16. 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

  17. 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);

  18. 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 ...

  19. 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.

  20. 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.

  21. 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.

More Related