Java-Persistenz-Architekturen Rudolf Jansen Freiberuflicher Entwickler und Autor http://www.rudolf-jansen.de info@rudolf-jansen.de DOAG Konferenz 1.12.2008
Inhalt JDBC JPA (Java Persistence API) Spring Alternative Architekturen( Java in der DB, Java Embedded Databases ) Vergleich, Diskussion
JDBC-Historie Java DataBase Connectivity Zugriff auf DB über Java-API-Funktionen ResultSet resset = stmt.executequery("select prs_vorname, prs_nachname from person"); Abbildung auf konkrete Datenbank durch JDBC- Treiber Portabilität (theoretisch) Historie: - JDBC 1.0 (1997, JDK 1.1) - JDBC 2.0 (JDK 1.2) - JDBC 3.0 (2002, JDK 1.4) - JDBC 4.0 (2006, Java SE 6)
JDBC: Pro und Contra Manuelle JDBC-Programmierung: Wer macht das denn heute noch? Vorteil : Programmieren ganz nah an der Datenbank Nachteil : SQL-Statements direkt im Sourcecode - Wartbarkeit - Portabilität - viel Handarbeit nötig (Fehleranfällig) -
JDBC: Pro und Contra Vielzahl von höherwertigen Techniken und Tools, die auf JDBC aufbauen: - Java Persistence API (JPA) - Spring - Hibernate - JDO - EJB -
JDBC-ExceptionHandling Connection con = null; Statement stmt = null; try{ con = getdatasource().getconnection(); stmt = con.preparestatement( select ); ResultSet resset = stmt.executequery();... stmt.close(); con.close(); } catch (SQLException ex) { }
JDBC-ExceptionHandling Connection con = null; Statement stmt = null; try{ con = getdatasource().getconnection(); stmt = con.preparestatement( select ); ResultSet resset = stmt.executequery();... Was passiert, wenn hier ein stmt.close(); Fehler auftritt? con.close(); } catch (SQLException ex) { }
JDBC-ExceptionHandling Connection con = null; Statement stmt = null; try{ con = getdatasource().getconnection(); stmt = con.preparestatement( select ); ResultSet resset = stmt.executequery();... Was passiert, wenn hier ein stmt.close(); Fehler auftritt? con.close(); Ressourcen werden nicht } catch (SQLException ex) { freigegeben!!! }
JDBC-ExceptionHandling Connection con = null; Statement stmt = null; try{ con = getdatasource().getconnection(); stmt = con.preparestatement( select ); ResultSet resset = stmt.executequery();... stmt.close(); con.close(); } catch (SQLException ex) { } finally { if ( stmt!= null ){ try { stmt.close(); } catch (SQLException ex) { } } // analog con.close() }
JDBC - Diskussion Weit verbreitet (Studium, Bücher, Schulungen, ) ABER: viel Handarbeit nötig - Wartungsaufwand - Sourcecode-Umfang und Übersichtlichkeit Kritiker: JDBC nur für Kleinprojekte - Suche nach Alternativen (nicht nur für Enterprise-Anwendungen)
Java EE / EJB-Persistenz EJB (Enterprise Java Beans) Einführung 1998 - Beginn des Siegeszuges Java auf dem Server - Auszug aus der EJB 1.0 Spezifikation: Enterprise JavaBeans will make it easy to write applications. Application developers will not have to understand low-level transaction and state management details; multi-threading; resource pooling; and other complex low-level APIs
Java EE / EJB-Persistenz Praxis-Erfahrungen mit EJB 1.0 und 2.0 Nimmt dem Entwickler viel Arbeit ab bei - Transaktionssteuerung - Skalierbarkeit - Sicherheit Macht dem Entwickler aber viel Arbeit bei - Persistenzfragen o Performance o Keine Vererbung möglich o Komplexität o Nur in EJB-Anwendungen einsetzbar (kein Java SE) Als reine Persistenzlösung sind EJBs (<Version 3.0) unnötig komplex
Java-Persistenz Stand in den Jahren 2004/2005 Java SE Java EE JDBC Hibernate EJB 2.x Eigene Frameworks JDO
Java-Persistenz Stand in den Jahren 2004/2005 Java SE Java EE JDBC Hibernate EJB 2.x Eigene Frameworks JDO Konkurrenzkampf
Java-Persistenz ab dem Jahr 2006 Java SE Java EE JDBC Hibernate EJB 3.0 Eigene Frameworks Java Persistence API (JPA) JDO
Java Persistence API Entstanden im Rahmen der EJB 3.0- Spezifikation Eigene Spezifikation (JSR 220) Ideengeber : - JDO - Hibernate - TopLink - Schlechte Erfahrungen mit EJB JPA = Spezifikation - Implementierung u.a. durch Hibernate Persistenzlösung für Java EE und Java SE!!! Einsatz von Java 5-Features (Annotations)
Java Persistence API Ziel: Keine (bzw. minimale) Vorgaben für Persistenzaspekte - Verwendung von POJOs (Plain Old Java Objects) Vererbung Einsatz von Java 5-Features (Annotations) Keine Abhängigkeit von Containern, Application Servern etc. Keep it simple
Java Persistence API Zentrale Komponente von JPA: Entity Normale Java-Klasse - Vererbung möglich - Keine Vorgaben durch Basisklassen - Keine Vorgaben durch Schnittstellen POJO
Java Persistence API @Entity public class Buch implements Serializable{ @Id private int id; private String titel; public Buch(){} public int getid() { return id;} public void setid( int id ){ this.id=id } public String gettitel() { return titel;} public void settitel( String titel ){ this.titel = titel;} }
Java Persistence API Buch - Id - titel JPA EntityManager Tabelle BUCH ID Titel 4711 xyz 4712 blabla
Java Persistence API Buch - Id - titel JPA EntityManager Bietet Methoden zum - Anlegen - Ändern - Löschen - Verwalten von POJOs (Instanzen von Buch) Tabelle BUCH ID Titel 4711 xyz 4712 blabla
Java Persistence API Configuration by Exception Anzahl der zur Konfiguration benötigten Annotations soll minimiert werden Sinnvolle Defaults Nur Ausnahmen explizit angeben Beispiel: Defaultregeln für Mapping Java-Klasse Datenbanktabelle: - Klassenname = Tabellenname - Attributname = Spaltenname Abweichungen von diesen Regeln müssen per Annotation angegeben werden
Java Persistence API Buch - Id - titel JPA EntityManager Tabelle BIBLIOTHEK ID Name 4711 xyz 4712 blabla
Java Persistence API @Entity @Table(name= BIBLIOTHEK ) public class Buch implements Serializable{ @Id private int id; @Column(name= NAME ) private String titel; public Buch(){} public int getid() { return id;} public void setid( int id ){ this.id=id } public String gettitel() { return titel;} public void settitel( String titel ){ this.titel = titel;} }
JPA - EntityManager Konfiguration/Initialisierung des EntityManager: EntityManagerFactory emf=persistence.createentitymanagerfactory( OracleTestDB"); EntityManager em=emf.getentitymanager(); EntityTransaction tx=em.gettransaction(); tx.begin(); Buch neuesbuch = new Buch(); neuesbuch.setid(4713); neuesbuch.settitel( Ein ganz neues Buch ); em.persist(neuesbuch); tx.commit(); em.close();
JPA - EntityManager Konfiguration/Initialisierung des EntityManager: EntityManagerFactory emf=persistence.createentitymanagerfactory( OracleTestDB"); EntityManager em=emf.getentitymanager(); EntityTransaction tx=em.gettransaction(); tx.begin(); Buch neuesbuch = new Buch(); neuesbuch.setid(4713); neuesbuch.settitel( Ein ganz neues Buch ); em.persist(neuesbuch); Woher kennt JPA die OracleTestDB? tx.commit(); em.close();
JPA - Konfiguration Datei persistence.xml: <persistence> <persistence-unit name= OracleTestDB"> <provider>oracle.toplink.essentials.ejb.cmp3.entitymanagerfactoryprovider</provider> <class>de.javastarterdays.buch</class> <properties> <!-- Provider-specific connection properties --> <property name="toplink.jdbc.driver" value="oracle.jdbc.driver.oracledriver"/> <property name="toplink.jdbc.url" value="jdbc:oracle:thin:scott/tiger@localhost:1521:xe"/> </properties> </persistence-unit> </persistence>
JPA Einträge finden und ändern EntityTransaction tx=em.gettransaction(); tx.begin(); Buch altesbuch = em.find(buch.class, 4711); if( altesbuch!= null ){ altesbuch.settitel( Ein geaenderter Titel ); } tx.commit();
JPA Abfragen Abfragen mit mehr als einem Ergebnis Query query = em.createquery( SELECT b FROM Buch b ) Collection buecher = query.getresultlist(); Abfragen mit genau einem Ergebnis Query query = em.createquery( SELECT b FROM Buch b WHERE b.id=:nr ); query.setparameter( nr, 4711); Buch dasgesuchtebuch = query.getsingleresult();
JPA Provider Übersicht über die bekanntesten Provider: Top Link OpenJPA Hibernate
Spring Ausgangspunkt EJB: Häufig genannte Kritik an EJB: - Komplexität - Zu viele Vorgaben, d.h. Klassen/Schnittstellen, die verpflichtend sind - Abhängigkeit von J2EE Container - Tests aufwändig - Performance bei Persistenzfragen kritisch - Abgrenzung J2EE J2SE Suche nach Alternativen
Spring - Historie Buch Expert One-on-One J2EE Design and Development Rod Johnson (2002) Begleitmaterial: Sourcecode für Applikationsframework Überführung in Open-Source-Projekt (2003) Name: Spring Heute: Populäres Open-Source-Framework Freie Nutzung Firma hinter Spring : SpringSource
Spring - Spring ist ein Framework Kein Produkt Keine Spezifikation Kein O/R-Mapping-Tool Bietet nicht nur Lösungen für Persistenz-Schicht, sondern viel mehr - Spring bietet Services an, um das Zusammenspiel von (Java-)Komponenten zu vereinfachen Einheitliche API-Schicht Abhängigkeiten zwischen Komponenten verwalten Aspekt-Orientierte Programmierung - Session Das SpringSource Advanced Pack for Oracle 13:00 Uhr
Spring und Persistenz Spring liefert keine eigene Persistenzlösung Stattdessen: Vereinfachung bei der Nutzung bestehender Persistenztechniken durch zusätzliche Abstraktionsschicht Spring kann zusammen mit allen bekannten Persistenztechniken eingesetzt werden: - JDBC - JDO - JPA - Hibernate -
Spring und Persistenz Spring vereinheitlicht Transaktionssteuerung, Exceptions, Verbindungshandling Hybride Ansätze möglich Entwickler implementiert nur die Businesslogik (Persistenz: Abfragen und Behandlung der Ergebnisse) Spring kümmert sich um den Rest Beispiel: JDBC Verbindungs- und Exceptionhandling
JDBC Connection con = null; Statement stmt = null; try{ con = getdatasource().getconnection(); stmt = con.preparestatement( select * from emp ); ResultSet resset = stmt.executequery();... stmt.close(); con.close(); } catch (SQLException ex) { } finally { if ( stmt!= null ){ try { stmt.close(); } catch (SQLException ex) { } } // analog con.close() }
JDBC Connection con = null; Statement stmt = null; try{ con = getdatasource().getconnection(); stmt = con.preparestatement( select * from emp ); ResultSet resset = stmt.executequery();... stmt.close(); con.close(); } catch (SQLException ex) { } finally { if ( stmt!= null ){ try { stmt.close(); } catch (SQLException ex) { } } // analog con.close() } Anwendungscode ist nur das! Rest ist - Verbindungshandling - Exception Handling und wird bei jedem JDBC-Zugriff benötigt ca. 80% des JDBC-Sourcecodes wiederholt sich
Spring Dasselbe mit Spring: public List getemplist() { return getjdbctemplate().queryforlist( select * from usertable ); } JdbcTemplate kümmert sich um den Rest DB-Zugriffsparameter in externer Konfigurationsdatei Eigene Spring-Exception-Hierarchie Exceptions unabhängig von verwendeter Technologie (JDBC- Exceptions ansonsten unterschiedlich zu Hibernate-EXceptions)
Inhalt JDBC JPA (Java Persistence API) Spring Alternative Architekturen (Java in der DB, Java Embedded DB ) Vergleich, Diskussion
Alternative Architekturen Bisher immer Standard-Architektur : Direktzugriff, z.b. JDBC Java-Anwendung Alternativen: Java in der Datenbank EJB, OR-Mapper, Datenbank in der Java-Anwendung Datenbank
Java in der Datenbank Java-Source-Code (*.java) Java-Class-Dateien (*.class) JAR-Archive (*.jar) loadjava Oracle-DB Java- Compiler Java- Sourcen Java- Klassen Java- Ressourcen
Alternative Architekturen Bisher immer Standard-Architektur : Direktzugriff, z.b. JDBC Java-Anwendung Alternativen: Java in der Datenbank EJB, OR-Mapper, Datenbank in der Java-Anwendung Datenbank
Java Embedded Datenbanken Einsatzgebiete: - Speicherung von Konfigurationsdaten - Ablage temporärer Nutzerdaten -... (andere Mini-Persistenz-Anforderungen ) Standardalternativen: - Speicherung in Betriebssystem-Datei - Speicherung in richtiger Datenbank
Java Embedded Datenbanken Standardalternativen: Speicherung in Betriebssystem-Datei: + Schnell implementiert - Sicherheit, Transaktionen, Backup, Speicherung in richtiger Datenbank: + Sicherheit, Transaktionen, Backup, - Kosten, Administration beim Endbenutzer erforderlich, Kompromisslösung: Embedded Datenbank
Java Embedded Datenbanken Java-Anwendung JDBC Java- Embedded- Datenbank JVM
Inhalt JDBC JPA (Java Persistence API) Spring Alternative Architekturen (Java in der DB, Java Embedded DB ) Vergleich, Diskussion
Auswahl der richtigen Persistenzstrategie Entscheidungskriterien Art der Java-Anwendung (J2SE, J2EE, J2ME) Meist: Persistenz nicht einzige Fragestellung Größe des Projektes Erfahrung mit Frameworks (Unterstützung der eingesetzten Datenbank) In bestehenden Projekten meist keine Wahl mehr
Auswahl der richtigen Persistenzstrategie Einige Lösungsansätze: Kleine Projekte mit einfachen DB-Zugriffen JDBC Neue Enterprise-Anwendungen JPA Hibernate Spring als Empfehlung für umfassendes Framework (nicht nur für Persistenz) Eigenentwicklung von Frameworks eher meiden