jpaAan de slag met jpa


Opmerkingen

JPA is de Java Persistence API, een specificatie voor het in kaart brengen van Java-objecten en hun relaties met een relationele database. Dit wordt een object-relationele mapper (ORM) genoemd. Het is een alternatief voor (of aanvulling op) de meer low-level JDBC . Het is vooral handig bij het volgen van een Java-georiënteerde benadering en wanneer complexe objectgrafieken moeten worden gehandhaafd.

JPA is op zichzelf geen implementatie. Daarvoor heeft u een persistentieprovider nodig (zie voorbeelden). Huidige implementaties van de nieuwste JPA 2.1-standaard zijn EclipseLink (ook de referentie-implementatie voor JPA 2.1, wat betekent "bewijs dat de specificatie kan worden geïmplementeerd"); Slaapstand en DataNucleus .

metadata

De toewijzing tussen Java-objecten en databasetabellen wordt gedefinieerd via persistentie-metagegevens . De JPA-provider gebruikt de persistentie-metagegevensinformatie om de juiste databasebewerkingen uit te voeren. JPA definieert meestal de metagegevens via annotaties in de Java-klasse.

Object-relationele entiteitsarchitectuur

De entiteitsarchitectuur bestaat uit:

  • entiteiten
  • persistentie-eenheden
  • persistentie contexten
  • fabrieken van entiteitsmanagers
  • entiteit managers

versies

Versie Deskundigengroep Vrijlating
1.0 JSR-220 2006-11-06
2.0 JSR-317 2009-12-10
2.1 JSR-338 2013/05/22

Hallo Wereld

Laten we alle basiscomponenten bekijken om een eenvoudige Hallo World te maken.

  1. Bepaal welke implementatie van JPA 2.1 we zullen gebruiken
  2. Bouw de verbinding met de database en creëer de persistence-unit
  3. Implementeert de entiteiten
  4. Implementeert DAO (Data access object) voor het manipuleren van de entiteiten
  5. Test de applicatie

bibliotheken

Met maven hebben we deze afhankelijkheden nodig:

<dependencies>

    <!-- JPA is a spec, I'll use the implementation with HIBERNATE -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>5.2.6.Final</version>
    </dependency>

    <!-- JDBC Driver, use in memory DB -->
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.193</version>
    </dependency>

</dependencies>
 

Persistentie-eenheid

In de map resources moeten we een bestand maken met de naam persistence.xml . De eenvoudigste manier om het te definiëren is als volgt:

<persistence-unit name="hello-jpa-pu" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

    <properties>
        <!-- ~ = relative to current user home directory -->
        <property name="javax.persistence.jdbc.url" value="jdbc:h2:./test.db"/>
        <property name="javax.persistence.jdbc.user" value=""/>
        <property name="javax.persistence.jdbc.password" value=""/>
        <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
        <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
        <property name="hibernate.show_sql" value="true"/>

        <!-- This create automatically the DDL of the database's table -->
        <property name="hibernate.hbm2ddl.auto" value="create-drop"/>

    </properties>
</persistence-unit>
 

Een entiteit implementeren

Ik maak een klasse Biker :

package it.hello.jpa.entities;


import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
import java.util.List;

@Entity
@Table(name = "BIKER")
public class Biker implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "bikerName")
    private String name;

    @Column(unique = true, updatable = false)
    private String battleName;

    private Boolean beard;

    @Temporal(TemporalType.DATE)
    private Date birthday;

    @Temporal(TemporalType.TIME)
    private Date registrationDate;

    @Transient // --> this annotiation make the field transient only for JPA
    private String criminalRecord; 

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getBattleName() {
        return battleName;
    }

    public void setBattleName(String battleName) {
        this.battleName = battleName;
    }

    public Boolean getBeard() {
        return this.beard;
    }

    public void setBeard(Boolean beard) {
        this.beard = beard;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public Date getRegistrationDate() {
        return registrationDate;
    }

    public void setRegistrationDate(Date registrationDate) {
        this.registrationDate = registrationDate;
    }

    public String getCriminalRecord() {
        return criminalRecord;
    }

    public void setCriminalRecord(String criminalRecord) {
        this.criminalRecord = criminalRecord;
    }
}
 

Implementeer een DAO

package it.hello.jpa.business;

import it.hello.jpa.entities.Biker;

import javax.persistence.EntityManager;
import java.util.List;

public class MotorcycleRally {

    public Biker saveBiker(Biker biker) {
        EntityManager em = EntityManagerUtil.getEntityManager();
        em.getTransaction().begin();
        em.persist(biker);
        em.getTransaction().commit();
        return biker;
    }

}
 

EntityManagerUtil is een singleton:

package it.hello.jpa.utils;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class EntityManagerUtil {

    // USE THE SAME NAME IN persistence.xml!
    public static final String PERSISTENCE_UNIT_NAME = "hello-jpa-pu";

    private static EntityManager entityManager;

    private EntityManagerUtil() {
    }

    public static EntityManager getEntityManager() {
        if (entityManager == null) {
            // the same in persistence.xml
            EntityManagerFactory emFactory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);


            return emFactory.createEntityManager();
        }
        return entityManager;
    }
}
 

Test de applicatie

pakket it.hello.jpa.test;

openbare klasse TestJpa {

@Test
public void insertBiker() {
    MotorcycleRally crud = new MotorcycleRally();

    Biker biker = new Biker();
    biker.setName("Manuel");
    biker.setBeard(false);

    biker = crud.saveBiker(biker);

    Assert.assertEquals(biker.getId(), Long.valueOf(1L));
}
 

}

De output zal zijn:

Het uitvoeren van it.hello.jpa.test.TestJpa Slaapstand: drop-tabel BIKER indien bestaat Slaapstand: drop-volgorde indien bestaat hibernate_sequence Slaapstand: maak reeks hibernate_sequence start met 1 stap met 1 Slaapstand: maak tabel BIKER (id bigint niet null, battleName varchar (255) ), baard boolean, geboortedatum, bikerName varchar (255), registratieDatum tijd, primaire sleutel (id)) Slaapstand: tabel wijzigen BIKER toevoegen beperking UK_a64ce28nywyk8wqrvfkkuapli uniek (battleName) Slaapstand: invoegen in BIKER (battleName, baard, verjaardag, bikerName, registratiedatum , id) waarden (?,?,?,?,?,?) 01 maart 2017 11:00:02 PM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation INFO: HHH000204: Processing PersistenceUnitInfo [naam: hallo- jpa-pu ...] Resultaten:

Tests uitgevoerd: 1, fouten: 0, fouten: 0, overgeslagen: 0

Installatie of instellingen

Classpath-vereisten

Eclipselink

De Eclipselink en JPA API moeten worden opgenomen. Voorbeeld Maven-afhankelijkheden:

<dependencies>
  <dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>eclipselink</artifactId>
    <version>2.6.3</version>
  </dependency>
  <dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>javax.persistence</artifactId>
    <version>2.1.1</version>
  </dependency>
  <!-- ... -->
</dependencies>
 

Hibernate

Hibernate-core is vereist. Voorbeeld Maven-afhankelijkheid:

<dependencies>
  <dependency>
    <!-- requires Java8! -->
    <!-- as of 5.2, hibernate-entitymanager is merged into hibernate-core -->
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.2.1.Final</version>
  </dependency>
  <dependency>
    <groupId>org.hibernate.javax.persistence</groupId>
    <artifactId>hibernate-jpa-2.1-api</artifactId>
    <version>1.0.0</version>
  </dependency>
  <!-- ... -->
</dependencies>
 

DataNucleus

datanucleus-core, datanucleus-api-jpa en datanucleus-rdbms (bij gebruik van RDBMS-datastores) zijn vereist. Voorbeeld Maven-afhankelijkheid:

<dependencies>
  <dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-core</artifactId>
    <version>5.0.0-release</version>
  </dependency>
  <dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-api-jpa</artifactId>
    <version>5.0.0-release</version>
  </dependency>
  <dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>datanucleus-rdbms</artifactId>
    <version>5.0.0-release</version>
  </dependency>
  <dependency>
    <groupId>org.datanucleus</groupId>
    <artifactId>javax.persistence</artifactId>
    <version>2.1.2</version>
  </dependency>
  <!-- ... -->
</dependencies>
 

Configuratiegegevens

JPA vereist het gebruik van een bestand persistence.xml , gelegen onder META-INF vanuit de root van het CLASSPATH. Dit bestand bevat een definitie van de beschikbare persistentie-eenheden waarmee JPA kan werken.

Met JPA kunt u bovendien een configuratiebestand voor toewijzingen orm.xml gebruiken , ook geplaatst onder META-INF . Dit toewijzingsbestand wordt gebruikt om te configureren hoe klassen worden toegewezen aan de gegevensopslag en is een alternatief / aanvulling op het gebruik van Java-annotaties in de JPA-entiteitsklassen zelf.

Minimaal persistence.xml-voorbeeld

Slaapstand (en ingesloten H2 DB)

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
                             http://java.sun.com/xml/ns/persistence/persistence_2_1.xsd"
         version="2.1">

<persistence-unit name="persistenceUnit">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>

    <class>my.application.entities.MyEntity</class>
    
    <properties>
        <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" /> 
        <property name="javax.persistence.jdbc.url" value="jdbc:h2:data/myDB.db" /> 
        <property name="javax.persistence.jdbc.user" value="sa" /> 

        <!-- DDL change options -->
        <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>

        <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
        <property name="hibernate.flushMode" value="FLUSH_AUTO" /> 
    </properties>
</persistence-unit>
</persistence>
 

Eclipselink (en embedded H2 DB)

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
                             http://java.sun.com/xml/ns/persistence/persistence_2_1.xsd"
         version="2.1">

<persistence-unit name="persistenceUnit">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>

    <class>my.application.entities.MyEntity</class>
    
    <properties>
        <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
        <property name="javax.persistence.jdbc.url" value="jdbc:h2:data/myDB.db"/>
        <property name="javax.persistence.jdbc.user" value="sa"/>

        <!-- Schema generation : drop and create tables -->
        <property name="javax.persistence.schema-generation.database.action" value="drop-and-create-tables" />
    </properties>
</persistence-unit>

</persistence>
 

DataNucleus (en embedded H2 DB)

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
                             http://java.sun.com/xml/ns/persistence/persistence_2_1.xsd"
         version="2.1">

<persistence-unit name="persistenceUnit">
    <provider>org.datanucleus.api.jpa.PersistenceProviderImpl</provider>

    <class>my.application.entities.MyEntity</class>
    
    <properties>
        <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
        <property name="javax.persistence.jdbc.url" value="jdbc:h2:data/myDB.db"/>
        <property name="javax.persistence.jdbc.user" value="sa"/>

        <!-- Schema generation : drop and create tables -->
        <property name="javax.persistence.schema-generation.database.action" value="drop-and-create-tables" />
    </properties>
</persistence-unit>

</persistence>