Java Persistence API

Willemers Informatik-Ecke

Das einzig seriöse Javabuch :-) Mehr...

Bei Amazon bestellen
JEE-Literatur
2017-05-10
Die Java Persistence API (JPA) bildet Objekte auf Datenbanktabellen ab. Es stellt so den Vermittler zwischen der objektorientierten Java-Welt und dem Zugriff auf relationale Datenbanken. Die Zuordnung und Übertragung von Objekten zu Datenbankeinträgen wird als Object Relational Mapping (ORM) bezeichnet.

Für die Verbindung zur Datenbank verwendet JPA den JDBC-Datenbanktreiber, der zusätzlich zum Projekt eingebunden werden muss.

Persistence Provider

Die JPA gehört nicht zum Standard-Umfang der Java Standard Edition oder Tomcat. In diesen Fällen muss die Bibliothek des Persistence Providers eingebunden werden. Diese JAR wird unter Eclipse bei Anlegen eines JPA-Projekts gleich angefordert und bei Bedarf automatisch heruntergeladen.

Es gibt mehrere Persistence Provider. Zu den bekanntesten gehören folgende:

Eclipse-Unterstützung für Standalone-Anwendungen

Eclipse stellt für Standalone-Anwendungen ein eigenes JPA-Projekt zur Verfügung. Es ist erzeugt, indem New | JPA Project ausgewählt wird. In dem Dialog müssen folgende Informationen abgelegt werden. JPA bietet unter Eclipse eine eigene Perspektive. Dazu werden weitere Fenster wie auf der linken Seite ein Data Source Explorer und auf der rechten Seite die JPA-Details angezeigt.

Entity

JPA bildet eine Datenbanktabellenzeile auf ein Java-Objekt ab. Ein solches Objekt wird als ganz gewöhnliche Java-Klasse beschrieben. Aus Sicht der JPA wird sie als Entity betrachtet und mit einer entsprechenden Annotation als solche gekennzeichnet..

Im Beispiel wird eine Datenbanktabelle GAST durch eine Klasse Gast abgebildet. Diese Zuordnung wird durch die Annotation @Entity angezeigt. Mit der Annotation @Id wird der Schlüssel der Tabelle markiert.

import java.io.Serializable;

@Entity(name="Gast")
public class Gast implements Serializable {
    @Id
    @GeneratedValue
    private Long id;
    @Column
    private String name;
    @Column
    private String mail;

    public Gast() {
    }

    public Long getId() { return id; }
    public String getName() { return name; }
    public String getMail() { return mail; } 
    public void setId(Long id) { this.id = id; } 
    public void setName(String name) { this.name = name; }
    public void setMail(String mail) { this.mail = mail; }
    
    public String toString() {
        return id + ": " + name + " - " + mail;
    }
}

persistence.xml

Für den Zugriff auf die Datenbank wird ein JDBC-Treiber benötigt. Durch diesen wird festgelegt, welche Datenbank verwendet wird, wo sie sich befindet und gegebenenfalls auch die Anmeldekennung dafür. Diese Informationen werden in der Datei persistence.xml definiert, die sich im Projektverzeichnis META-INF befindet.

Die Datei definiert auch die Persistence Unit, die im Programm von der EntityManagerFactory aufgegriffen wird.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="gastPU" transaction-type="RESOURCE_LOCAL">
        <class>Gast</class>
        <properties>
          <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
          <property name="javax.persistence.jdbc.url" value="jdbc:derby:/home/arnold/databases/simpleDb;create=true" />
          <property name="javax.persistence.jdbc.user" value="test" />
          <property name="javax.persistence.jdbc.password" value="test" />

          <!-- EclipseLink should create the database schema automatically -->
          <property name="eclipselink.ddl-generation" value="create-tables" />
          <property name="eclipselink.ddl-generation.output-mode" value="database" />
        </properties>
    </persistence-unit>
</persistence>

EntityManager und seine Factory

Der EntityManager sorgt dafür, dass die Daten zwischen Datenbanktabelle und den Java-Objekten hin und her gehen. Einen EntityManager erhalten Sie, indem Sie ihn durch eine EntityManagerFactory erzeugen. Die Factory wiederum erhält den Namen der Persistence Unit, die in der Datei persistence.xml beschrieben wird.

Anfragen

Über die Methode createQuery können SQL-Anfragen an die Datenbank gestellt werden. Als Parameter erhält sie den SQL-Befehl. Der Rückgabewert ist von der Klasse Query.

Über dieses Query-Objekt können Sie die Methode getResultList aufrufen, die Ihnen eine Liste aller gefundenen Elemente liefert.

Änderungen an der Datenbank

Bei den meisten Datenbanken erfolgen Änderungen im Zusammenhang mit einer Transaktion. Eine Transaktion garantiert einen konsistenten Zustand. Sollte es nach der Transaktion nicht möglich sein, einen konsistenten Zustand zu erreichen, wird die Datenbank in den vorherigen Zustand überführt.

Entsprechend wird zunächst die Transaktion des Managers eingeläutet. Mit der Methode persist wird die Änderung in die Datenbank geschrieben. Anschließend wird die Transaktion beendet.

manager.getTransaction().begin();
manager.persist(Datenobjekt);
manager.getTransaction().end();

Hauptprogramm

import java.util.List;

public class Main {
    
    static EntityManagerFactory factory = null;
    
    private static Gast createGast (
            String name, String mail) {
        Gast gast = new Gast();
        gast.setName(name);
        gast.setMail(mail);
        return gast;
    }
    
    private void speichere(EntityManager manager, Gast gast) {
        manager.getTransaction().begin();
        manager.persist(gast);
        manager.getTransaction().commit();
    }
    
    private void zeige(EntityManager manager) {
        TypedQuery query = manager.createQuery("select t from Gast t", Gast.class);
        List liste = query.getResultList();
        for (Gast gast : liste) {
            System.out.println(gast);
        }
    }
    
    private void suche(EntityManager manager, String name) {
        TypedQuery query = manager.createQuery(
                "select +"
                + "t from Gast t where t.name=:name",
                Gast.class);
        query.setParameter("name", name);
        List liste = query.getResultList();
        for (Gast gast : liste) {
            System.out.println(gast);
        }
    }
    
    public Main() {
        EntityManager manager = factory.createEntityManager();
        // Testdaten erzeugen
        speichere(manager, createGast("Bedman", "bed@man"));
        speichere(manager, createGast("Sabber", "sbbr@man"));
        // Daten auslesen und anzeigen
        zeige(manager);
        suche(manager, "Bedman");
        manager.close();
    }
    
    public static void main(String[] args) {
        factory = Persistence.createEntityManagerFactory("gastPU");
        new Main();
        factory.close();
    }
}

Zu JPA siehe auch: Christian Dürr: Grundlagen der JPA

JEE-Literatur

Marcus Schießer, Martin Schmollinger: Workshop Java EE 7

Etwas abstrakter: Dirk Weil: Java EE 7: Enterprise-Anwendungsentwicklung leicht gemacht

Nicht JEE, sondern grundlegendes Java für Java-Anfänger: Arnold Willemer: Java


Homepage (C) Copyright 2013, 2017 Arnold Willemer