Stunde4.ink Persistenz von Objekten relationale Datenbank Eigene Datenstruktur XML (JAXB) Proprietäre Dateiformate (Lochkarten) O/R Mapping - Objekte (Attribute) - 1:1, 1:n, n:m Beziehungen - Vererbungen (- Interfaces) 1:1 Beziehungen 1 Stunde4.ink 1:n Beziehungen n:m-Beziehung 2 Stunde4.ink Vererbung 3 Stunde4.ink JDBC (Java Database Connectivity) JDBC ist API, mit der aus Java-Programmen auf Datenbanken zugegriffen werden kann. Es gibt folgende Klassen: 4 Stunde4.ink Connection Bildet Kommunikation mit Datenbank und übernimmt Transaktionssteuerung Connection connection = DriverManager.getConnection( "jdbc:odbc:fhkn", "username", "passwort"); Statement Realsisiert genau eine Datenbankaktion (z.B. update, select, ....) Statement statement = connection.createStatement(); statement.execute("UPDATE GAME SET TITLE = 'Endspiel'"); ResultSet Liefert Ergebnismenge einer Datenbankabfrage und erlaubt Aktualisierungen und Rückschreiben in Datenbank. ResultSet resultSet = statement.executeQuery("SELECT * from USER"); while (resultSet.next()) { String loginName = resultSet.getString("loginname"); int plz = resultSet.getInt("PLZ"); } Name der Spalte 5 Stunde4.ink Datentypen in Java und SQL - String <=> VARCHAR - java.util.Timestamp <=> TIMESTAMP - java.util.Date <=> DATE - double <=> DOUBLE, FLOAT - float <=> REAL - boolean <=> BIT - int <=> INTEGER http://java.sun.com/j2se/1.3/docs/guide/jdbc/getstart/mapping.html#table1 6 Stunde4.ink 7 Stunde4.ink Hibernate 1. Einführung http://www.hibernate.org/hib_docs/v3/reference/en/html Hibernate ist ein O/R Mappern, um Java Objekte (POJO = Plain Old Java Objects) in einer Datenbank zu speichern. Alternativen zu Hibernate sind - JDBC - JDO - EJB - OO-Datenbanken Der künftige EJB Standard 3.0 wird voraussichtlich auf Hibernate basieren. Im Gegensatz zu einigen JDO Implementierungen verändert Hibernate die kompilierten Klassen nicht (durch Bytecode-Enhancement), nutzt aber ebenso JDBC, was für den Nutzer nicht erkennbar ist. 8 Stunde4.ink Code-Beispiel Session session = HibernateSessionFactory.createSession(); Transaction transaction = session.beginTransaction(); User user = new User ("hans"); session.saveOrUpdate(user); transaction.commit(); 2. Konfiguration von Hibernate Die HibernateSessionFactory erzeugt eine (Hibernate-) Session als Singleton und liest dabei eine Konfigurationsdatei hibernate.cfg.xml ein, die u.a. Folgendes bestimmt: - Benutzername - Passwort - Datenbank (und Datenbankdialekt) - Host/Datenbanktreiber - Liste aller Konfigurationsdateien pro Klasse 9 Stunde4.ink 3. Konfigurationsdateien pro Klasse - Klasse, Package - Attribute, die zu mappen sind - optional: wie Attribute zu mappen sind - Spaltenname - 1:1, 1:n, n:m Beziehungen - Primärschlüssel a) Primärschlüssel 1. Möglichkeit: Applikation vergibt Primärschlüssel: <?xml version="1.0"?> <!DOCTYPE .. > <hibernate-mapping package="de.fhkn.sem6.fifa"> <class name="Game" discriminator-value="N"> <id name="title"/> </class> </hibernate-mapping> 2. Möglichkeit: Hibernate/DB vergibt Primärschlüssel: <?xml version="1.0"?> <!DOCTYPE .. > <hibernate-mapping package="de.fhkn.sem6.fifa"> <class name="Game" discriminator-value="N"> <id name="id" unsaved-values="null"/> <generator class="native"/> </id> </class> </hibernate-mapping> 10 Stunde4.ink b) 1:n Beziehungen Game tickets: Set<Ticket> title:String Ticket 1 n id:int game:Game <?xml version="1.0"?> <?xml version="1.0"?> <!DOCTYPE .. > <!DOCTYPE .. > <hibernate-mapping package="de.fhkn.sem6.fifa"> <hibernate-mapping package="de.fhkn.sem6.fifa"> <class name="Game" discriminator-value="N"> <class name="Ticket" discriminator-value="N"> .. .. <property name="title" column="Spielname" length="35"/> <many-to-one name="game"/> <set name="tickets"> .. <key column="id"/> </class> <one-to-many class="Ticket"/> </hibernate-mapping> </set> .. </class> </hibernate-mapping> 11 Stunde4.ink c) Mappen von Collections <?xml version="1.0"?> <!DOCTYPE .. > <hibernate-mapping package="de.fhkn.sem6.fifa"> <class name="User" discriminator-value="N"> .. <map name="details"> <key column="detailskey"/> <index column="UserAttribute" type="de.fhkn.sem6.fifa.HibernateUserAttribute"/> <element type="string"/> </map> .. </class> </hibernate-mapping> 12 Stunde4.ink 4. Laden von Werten aus der Datenbank a) Objekt mit Primärschlüssel holen User user = (User)session.load(User.class, "hans"); b) Laden anhand von Kriterien (Queries) Query query = session.createQuery( "from User as u where u.loginname = ?"); query.setString(0, "hans"); Mit Iterator oder Liste weiterarbeiten: Iterator<User> iterator = query.createIterator(); List<User> list = query.list(); 13 Stunde4.ink Zum Abschluss: Vom Klassendiagramm zur Datenbank package de.fhkn.sem6.fifa; import org.hibernate.tool.hbm2ddl.SchemaUpdate; public class GenerateDDLStatements { public static void main(String[] args) { SchemaUpdate su = new SchemaUpdate(HibernateSessionFactory.getCfg()); su.execute(true, true); } } 14 Stunde4.ink Java 5 - Neue Sprachmerkmale 1. Generics Bisher boten Container (Map, Collection) keine Typsicherheit an. Damit konnte zur Laufzeit eine ClassCastException auftreten: alt: Map users = new HashMap(); users.put("hans", new User("Hans"); User user = (User)users.get("hans"); neu Map<String, User> users = new HashMap<String, User>(); users.put("hans", new User("Hans"); User user = users.get("hans"); 2. Iteratoren neu: Iterator<User> userIterator = users.iterator(); User user = userIterator.next(); //ohne Cast 15 Stunde4.ink 3. Loops For Loop alt: for (int i = 0; i < users.size(); i++) { ... } neu: for (User user : users) { ... } 4. Autoboxing Unter Autoboxing versteht man die automatische Konvertierung von primitiven Datentypen in die zugehörigen Objekte (und umgekehrt): tickets.put(3, new Ticket("Endspiel"); System.out.println("Die Summe von 1 und 2:" + (new Integer(1) + new Integer(2))); 16 Stunde4.ink 4. Static Imports Import-Statements für statische Methoden: alt: Integer.parseInt(); import static java.lang.Integer.*; import static java.lang.Integer.parseInt; im Code: parseInt("3"); 5. Enum Neues Schlüsselwort für Aufzählungtypen Beispiel: enum Type { vip, tribuene, curve}; public Ticket(Type typ) { } Alt: public final static String TRIBÜNE = "tribüne"; public final static String KURVE= "kurve"; public Ticket(String categorie) { ... } 17