Persistenz I Ralf Gitzel [email protected] 1 Themenübersicht Ralf Gitzel [email protected] 2 Übersicht • • • • Grundkonzepte Entity Beans Meine erste Entity Entity-Manager Die Schlüsselvariable 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 Das Datenmodell - Beispiel WorkOrder ____________ ID:long Description:String Status:WOStatus ResponsiblePerson Person ____________ Name:String Skills:List Beliebige Klassen, die mit ihren Variablen die „Wirklichkeit“ abbilden, die zueinander in Beziehung stehen. Ggf. beschreiben Methoden das Verhalten. 7 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 8 Vom Java Objekt zur Entity Java Objekt Annotationen Entity Annotationen Entity mit ORM 9 Meine erste Entity Ralf Gitzel [email protected] 10 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 11 Java Klasse – noch keine Entity! Vergebene Punktzahl Name (= eindeutiger Identifikator) Klasse speichert das Ergebnis einer Abstimmung. 12 Klasse: zwischenschritte.eins.PollResult Entity Bean Markierung als Entity Eindeutiger Identifikator (d.h. Schlüssel) 13 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. 14 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. 15 Datenbanktabelle: Umfrageergebnisse Tabelle mit Umfrageergebnissen Name der befragten Person Bewertung auf einer Skala 1 bis 10 Noch offen: Wie kann ich die Entity auf die Datenbank abbilden? 16 Abbildung auf Datenbank 17 @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 18 @Column • name: Name der Spalte in der angegebenen Tabelle • table: Nur relevant wenn man die Annotation @SecondaryTable verwendet hat • nullable: Darf in der Spalte ein Nullwert stehen? • unique: Muss der Wert in der Tabelle einmalig sein? • length, precision, scale: Nur bei bestimmten Datentypen relevant (s. Beispiele) • Anmerkung: Optionale Annotation - Wenn diese Angabe fehlt wird der Feldname als Spaltenname genommen. 19 Zusammenfassung Entities Entity Table Klasse Id Instanzvariable 1 = Column eindeutiger Identifikator Entity Annotationen Column Instanzvariable 2 Column Instanzvariable n ORM Annotationen 20 EntityManager (Teil 1) Ralf Gitzel [email protected] 21 Rolle des EntityManagers • Ein Objekt, das den Zugriff auf die Datenbank erlaubt • Die Details folgen später, hier der einfachste Fall der Anwendung 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/sample</jta-data-source> <properties> </properties> </persistence-unit> Name der Datenbank (s. </persistence> Anhang) Liegt im Verzeichnis META-INF 24 Schritt 2: Daten schreiben Objekterzeugung Parameter ist ein Objekt einer als Entity markierten Klasse 25 Schritt 3: Daten wieder lesen Daten aus der Tabelle auslesen über Primärschlüssel 26 Gesamtes Beispiel Klasse: entity.intro.firstbean.PollEntryCreator. Zu testen mit: index.html 27 Die Schlüssel-Variable Ralf Gitzel [email protected] 28 @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) 29 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“) 30 Erstellen einer Identity Column in Derby (Glassfish Datenbank) Automatischer Tabellenwert, beginnt bei 1, wird jedesmal um 1 erhöht 31 Entity Klasse Einziger Unterschied zu normaler Entity. Aber: Die Spalte muss in der DB entsprechend eingerichtet sein! 32 Klasse: entity.key.IDPerson Resultate in der Tabelle Mehrmals identischer Aufruf 33 Aufruf zum Test: http://localhost:8080/EntityIntroductionWeb/IDPersonServlet Entity Beziehungen (Teil 1) Ralf Gitzel [email protected] 34 Gruppendiskussion: Wie programmiere ich diese Beziehungen in (normalem) Java? hat Auto Fahrzeugschein hat Auto Fahrzeugschein gehörtZu vorderRad Rad 1 Motorrad hinterRad Rad 2 35 JEE Beziehungen • Basieren auf den „normalen“ Javareferenzen • Durch Annotationen wird das Mapping auf die Datenbank hergestellt • Alle beteiligten Klassen müssen Entities sein 36 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 37 Direktionalität • Uni-Directional: Die Verbindung ist nur auf einer Seite sichtbar. • Bi-Directional: Die Verbindung ist auf beiden Seiten sichtbar. 38 Fallübersicht @OneToOne (Unidirektional) @OneToOne (Bidirektional) @OneToMany (Unidirektional) @OneToMany (Bidirektional) @ManyToOne (Unidirektional) @ManyToOne (Bidirektional) @ManyToMany (Unidirektional) @ManyToMany (Bidirektional) 39 Fallübersicht @OneToOne (Unidirektional) @OneToOne (Bidirektional) @OneToMany (Unidirektional) @OneToMany (Bidirektional) @ManyToOne (Unidirektional) @ManyToOne (Bidirektional) @ManyToMany (Unidirektional) @ManyToMany (Bidirektional) 40 Übersicht EJB 1 Referenz Tabelle 1 Spalte X EJB 2 Tabelle 2 Fremdschlüssel Spalte Y 41 Beispiel Unidirektional 1-zu-1: Geheimagent mit Deckidentität 42 Tabelleneinträge Frage: Unter welcher Emailadresse erreicht man James Bond? 43 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) 44 Klasse CoverIdentity 45 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 46 Fallübersicht @OneToOne (Unidirektional) @OneToOne (Bidirektional) @OneToMany (Unidirektional) @OneToMany (Bidirektional) @ManyToOne (Unidirektional) @ManyToOne (Bidirektional) @ManyToMany (Unidirektional) @ManyToMany (Bidirektional) 47 Übersicht Referenz EJB 1 EJB 2 Referenz Tabelle 1 Spalte X Tabelle 2 Fremdschlüssel Spalte Y 48 Datenbankeintrag 49 Koffer-Klasse Genau wie vorher! Klasse: entity.intro.onetoone.Koffer Ausprobieren mit: KofferServlet 50 Griff-Klasse Keine @Column mappedBy (s. n. Folie) 51 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. 52 Lernziele Ralf Gitzel [email protected] 53 Lernziele • S. nächste Vorlesung für eine gemeinsame Übersicht 54 Übungsaufgabe Ralf Gitzel [email protected] 55 Aufgabenstellung: Nachrichten Webseite • Über ein Formular kann man eine Nachricht schreiben, versehen mit einer ID • Mittels der ID kann die Nachricht abgerufen werden. • Eine Nachricht besteht aus: Autorname, ID und Text. 56 Bonusmaterial Ralf Gitzel [email protected] 57 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 58 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. 59 Anhang: Aufsetzen der Datenbank Ralf Gitzel [email protected] 60 Einleitung • Die ersten Schritte können Sie überspringen, wenn Sie bereits einen Server aufgesetzt haben • Wichtig ist, die Schritte genau zu befolgen, denn man kommt schnell in eine Sackgasse 61 Neues Serverprofil erzeugen New > Server 62 Neues Serverprofil 63 Server Details Mit „Next“ zu dieser Seite, danach mit „Finish“ erzeugen. 64 Server Preferences Menu: Window > Preferences 65 Datenquelle anlegen „New“ im Kontextmenü um eine neue Database Connection Anzulegen. 66 Datenquelle anlegen Typ = Derby Name 67 Datenquelle anlegen Neuen Treiber (s. nächste Seite) Einstellungen I Einstellungen II 68 Neuer Treiber Jar List Reiter auswählen Jar-File (in GlassfishUnterordner: javadb/lib 69 Neuer Treiber 70 Datenbank anschauen Hier liegen später unsere Datenbanktabellen 71 Server Starten 72 Server konfigurieren Server kann über den Webbrower konfiguriert werden. 73 JDBC konfigurieren 1. Pool anlegen 74 Pool anlegen Beliebiger Name Derby = JavaDB 75 Datenbankparameter Herunterscrollen s. Folie „Datenquelle anlegen“ 76 JDBC Resource Neue Ressource erzeugen 77 JDBC Resource Wichtig: Unseren neu erzeugten Pool verwenden! 78 Tabellen in der Datenbank anlegen SQL Scrapbook öffnen 79 Befehl zum Anlegen der Tabelle Ausführen mit Rechtsklick und „Execute All“ 80 Resultat überprüfen Die neu angelegten Tabellen können in einer Entity verwendet werden. 81 Tabellendaten anzeigen/verändern Rechtsklick: Data > Edit 82