jpa Zelfstudie
Aan de slag met jpa
Zoeken…
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 |
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>
Hallo Wereld
Laten we alle basiscomponenten bekijken om een eenvoudige Hallo World te maken.
- Bepaal welke implementatie van JPA 2.1 we zullen gebruiken
- Bouw de verbinding met de database en creëer de
persistence-unit - Implementeert de entiteiten
- Implementeert DAO (Data access object) voor het manipuleren van de entiteiten
- 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