Persistenz Ralf Gitzel [email protected] 1 Themenübersicht Ralf Gitzel [email protected] 2 Übersicht • • • • • Grundkonzepte Entity Beans Meine erste Entity Entity-Manager Lernziele Übungsaufgabe 3 Grundkonzepte Entities Ralf Gitzel [email protected] 4 Konzept der Persistenz • Persistente Daten sind auch nach Beenden des Programms vorhanden. • Sie können bei erneutem Aufruf des Programms wieder rekonstruiert werden. • Klassisches Werkzeug für Persistenz ist die relationale Datenbank. 5 EJB Architektur Request Response Web Container View & Controller Servlet DB Persistence Provider EJB Container Model EJB 6 Umsetzung des Datenmodells in Entities • EJB 3 Java Persistence API (JPA) • Vorraussetzungen: – Markierung der Domänenobjekte – Eindeutige Identifizierung jedes Objekts (Schlüssel) – Definition der Objektbeziehungen – Definition von Regeln zum Speichern in/Laden aus einer Datenbank 7 Vom Java Objekt zur Entity Java Objekt Annotationen Entity Annotationen Entity mit ORM 8 Meine erste Entity Ralf Gitzel [email protected] 9 Hinweise • Anweisungen zum Konfigurieren der Datenbank (inkl. Anlegen der Tabellen) mit Glassfish finden sich im Anhang • In unseren Beispielen gehen wir immer davon aus, dass die Datenbanktabellen bereits existieren 10 Entity Bean Markierung als Entity Eindeutiger Identifikator (d.h. Schlüssel) 11 Eigenschaften einer Entity • Muss einen public-Konstruktor ohne Parameter haben • Kann von anderen Klassen erben • Kann abstrakt sein • Referenzierte Klassen müssen auch Entities oder serialisierbar sein Anm.: Ist gar kein Konstruktor definiert, so gibt es automatisch einen Public-Konstruktor ohne Parameter. 12 Markierungen für die Variablen • @Id: Der Primärschlüssel für dieses Objekt, d.h. der Identifikator • @Transient: Wird nicht mit abgespeichert, ist also beim Laden 0, null etc. 13 Datenbanktabelle: Personendaten Tabelle mit Personendaten Nachname Eintrag (Schlüssel) Noch offen: Wie kann ich die Entity auf die Datenbank abbilden? 14 Abbildung auf Datenbank 15 @Table • Namen der Tabelle angeben • Verwendet man diese Annotation nicht, so wird die Tabelle mit dem gleichen Namen wie die Entity verwendet • Optionale Parameter: catalogue, schema, uniqueConstraints 16 @Column • name: Name der Spalte in der angegebenen Tabelle • Anmerkung: Optionale Annotation Wenn diese Angabe fehlt wird der Feldname als Spaltenname genommen. 17 Zusammenfassung Entities Entity Table Klasse Id Instanzvariable 1 = Column eindeutiger Identifikator Entity Annotationen Column Instanzvariable 2 Column Instanzvariable n ORM Annotationen 18 EntityManager Ralf Gitzel [email protected] 19 Rolle des EntityManagers • Ein Objekt, das den Zugriff auf die Datenbank erlaubt • Hier betrachten wir nur den einfachsten Fall der Anwendung 20 Beispiel Personendaten sollen gespeichert und wieder geladen werden! 21 Datenbank 22 Schritt 1: Entity Manager erzeugen Wird durch Dependency Injection in die SessionBeanKlasse eingefügt 23 Persistence XML <?xml version="1.0" encoding="UTF-8"?> unitName <persistence> <persistence-unit name="test"> <jta-data-source>jdbc/sample2</jta-data-source> <properties> </properties> </persistence-unit> Name der Datenbank (s. </persistence> Anhang) Liegt im Verzeichnis META-INF 24 Schritt 2: Daten schreiben Objekt aus Servlet Aufruf des Entity Managers Datei: PersonenQuelle.java (eine Session Bean) 25 Schritt 3a: Daten wieder lesen Daten aus der Tabelle auslesen über Primärschlüssel Datei: PersonenQuelle.java (eine Session Bean) 26 Schritt 3b: Daten wieder lesen Komplexere Abfragen sind möglich Datei: PersonenQuelle.java (eine Session Bean) 27 Gesamtes Beispiel Datei: PersonenQuelle.java (eine Session Bean) 28 Lernziele Ralf Gitzel [email protected] 29 Lernziele • Wie mache ich aus einer Javaklasse eine Entity, wenn ich die Tabelle und die Spaltennamen kenne? • Nicht relevant: Enum, Persistence Provider • Muss nicht programmiert werden können 30 Übungsaufgabe Ralf Gitzel [email protected] 31 Aufgabenstellung • Hinweis: Diese Aufgabe dient zur Wiederholung von JSF als Klausurvorbereitung, d.h. es kommen keine Session Beans oder Entities darin vor. • Es soll eine Film“datenbank“ erstellt werden, bei der man Filme eingeben kann, die dann als Liste angezeigt werden. 32 Eingabe der Filmdaten Nochmal auf dieser Seite einen Film eingeben Letzte Eingabe – danach zur Filmliste wechseln 33 Ausgabe der Filme Icon zeigt die Bewertung von 1 bis 3 an! 34 Hinweise • Navigation soll über die Regeln erfolgen, auch wenn sie hier relativ einfach ist • Der Name der Bilder kann aus Text und Expression Language zusammengesetzt werden • Material: – Webseite zur Eingabe (ohne die ManagedBean) – Helferklasse zum Speichern von Filmen – Grafiken für die Bewertung 35 Anhang: Aufsetzen der Datenbank Ralf Gitzel [email protected] 36 Einleitung • Falls Sie Persistenz ausprobieren wollen, hier eine kurze Anleitung zum Einrichten der DB • Die ersten Schritte können Sie überspringen, wenn Sie bereits einen Server aufgesetzt haben 37 Neues Serverprofil erzeugen New > Server 38 Neues Serverprofil 39 Server Details Mit „Next“ zu dieser Seite, danach mit „Finish“ erzeugen. 40 Server Preferences Menu: Window > Preferences 41 Datenquelle anlegen „New“ im Kontextmenü um eine neue Database Connection Anzulegen. 42 Datenquelle anlegen Typ = Derby Name 43 Datenquelle anlegen Neuen Treiber (s. nächste Seite) Einstellungen I Einstellungen II 44 Neuer Treiber 45 Neuer Treiber Jar List Reiter auswählen Jar-File (in GlassfishUnterordner: javadb/lib 46 Datenbank anschauen Hier liegen später unsere Datenbanktabellen 47 Server Starten 48 Server konfigurieren Server kann über den Webbrower konfiguriert werden. 49 JDBC konfigurieren 1. Pool anlegen 50 Pool anlegen Beliebiger Name Derby = JavaDB 51 Datenbankparameter Herunterscrollen s. Folie „Datenquelle anlegen“ 52 JDBC Resource Neue Ressource erzeugen 53 JDBC Resource Wichtig: Unseren neu erzeugten Pool verwenden! 54 Tabellen in der Datenbank anlegen SQL Scrapbook öffnen 55 Befehl zum Anlegen der Tabelle Ausführen mit Rechtsklick und „Execute All“ 56 Resultat überprüfen Die neu angelegten Tabellen können in einer Entity verwendet werden. 57 Tabellendaten anzeigen/verändern Rechtsklick: Data > Edit 58 Anhang 2: Entity Beziehungen Ralf Gitzel [email protected] 59 Gruppendiskussion: Wie programmiere ich diese Beziehungen in (normalem) Java? hat Auto Fahrzeugschein hat Auto Fahrzeugschein gehörtZu vorderRad Rad 1 Motorrad hinterRad Rad 2 60 JEE Beziehungen • Basieren auf den „normalen“ Javareferenzen • Durch Annotationen wird das Mapping auf die Datenbank hergestellt • Alle beteiligten Klassen müssen Entities sein 61 Entity Beziehungen Beziehungstyp Annotation 1-zu-1: Ein Auto hat einen Motor und jeder Motor gehört zu genau einem Auto @OneToOne 1-zu-n: Eine Stadt hat mehrere Häuser @OneToMany n-zu-1: Ein Haus gehört zu einer Stadt @ManyToOne n-zu-n: Mehrere Personen können mehrere Konten haben @ManyToMany 62 Direktionalität • Uni-Directional: Die Verbindung ist nur auf einer Seite sichtbar. • Bi-Directional: Die Verbindung ist auf beiden Seiten sichtbar. 63 Fallübersicht @OneToOne (Unidirektional) @OneToOne (Bidirektional) @OneToMany (Unidirektional) @OneToMany (Bidirektional) @ManyToOne (Unidirektional) @ManyToOne (Bidirektional) @ManyToMany (Unidirektional) @ManyToMany (Bidirektional) 64 Fallübersicht @OneToOne (Unidirektional) @OneToOne (Bidirektional) @OneToMany (Unidirektional) @OneToMany (Bidirektional) @ManyToOne (Unidirektional) @ManyToOne (Bidirektional) @ManyToMany (Unidirektional) @ManyToMany (Bidirektional) 65 Übersicht EJB 1 Referenz Tabelle 1 Spalte X EJB 2 Tabelle 2 Fremdschlüssel Spalte Y 66 Beispiel Unidirektional 1-zu-1: Geheimagent mit Deckidentität 67 Tabelleneinträge Frage: Unter welcher Emailadresse erreicht man James Bond? 68 Klasse SecretAgent 1-zu-1 Beziehung Wert veränderbar? Spaltenname Spaltenname in der Zieltabelle Klasse: entity.intro.onetoone.SecretAgent Testen mit: AgentForm.html (aber vorher manuell Tabelle füllen) 69 Klasse CoverIdentity 70 Keine Referenz auf SecretAgent da unidirektional Optionale Parameter von @OneToOne • TargetEntity: Angabe des Namens der Ziel-Entity • Cascade • Fetch • Optional: Muss dieser Wert gesetzt sein oder nicht? • MappedBy: Für bidirektionale Verbindungen 71 Fallübersicht @OneToOne (Unidirektional) @OneToOne (Bidirektional) @OneToMany (Unidirektional) @OneToMany (Bidirektional) @ManyToOne (Unidirektional) @ManyToOne (Bidirektional) @ManyToMany (Unidirektional) @ManyToMany (Bidirektional) 72 Übersicht Referenz EJB 1 EJB 2 Referenz Tabelle 1 Spalte X Tabelle 2 Fremdschlüssel Spalte Y 73 Datenbankeintrag 74 Koffer-Klasse Genau wie vorher! Klasse: entity.intro.onetoone.Koffer Ausprobieren mit: KofferServlet 75 Griff-Klasse Keine @Column mappedBy (s. n. Folie) 76 Anmerkungen • mappedBy: – Referenz auf das Feld in der „Haupt“-Entity, welche auf diese Entity verweist. – Nur eine Entity in der Beziehung muss diesen Parameter haben. 77 Anhang 3: Alternative Schlüssel Ralf Gitzel [email protected] 78 Alternative Schlüsseldefinitionen Person __________________ Name (Key) Vorname (Key) Alter (Key) Geburtsort (Key) Wohnort Person __________________ Person_Id (Key) Wohnort @IdClass Autom. Erzeugung @EmbeddedId Referenz PersonID (Key) __________________ Name Vorname Alter Geburtsort PersonID (Key) __________________ Name Vorname Alter Geburtsort 79 Alternative Schlüsseldefinitionen • @IdClass: Zusammengesetzter Schlüssel, Objekt wird implizit aus allen Schlüsselfeldern erstellt • @EmbeddedId: Zusammengesetzter Schlüssel, der explizit durch eine Variable in der Klasse repräsentiert wird. 80 @Id - Erlaubte Typen • Primitive Datentypen (int etc.) und deren Wrapper (Integer etc.) • java.lang.String • java.lang.Date oder java.sql.Date • … • Hinweis: float und double vermeiden (wegen Genauigkeit der Kommastellen) 81 Verwenden von Surrogate Keys • Viele Datenbanken unterstützen die „automatische Erstellung“ von Schlüsseln, z.B. über Identity Columns • Dem Schlüsselfeld wird automatisch ein Wert zugewiesen, der nichts mit den Daten der Entity zu tun hat (d.h. z.B. „12567“ statt „Ralf Gitzel“) 82 Erstellen einer Identity Column in Derby (Glassfish Datenbank) Automatischer Tabellenwert, beginnt bei 1, wird jedesmal um 1 erhöht 83 Entity Klasse Einziger Unterschied zu normaler Entity. Aber: Die Spalte muss in der DB entsprechend eingerichtet sein! 84 Klasse: entity.key.IDPerson Resultate in der Tabelle Mehrmals identischer Aufruf 85 Aufruf zum Test: http://localhost:8080/EntityIntroductionWeb/IDPersonServlet