jpa Samouczek
Rozpoczęcie pracy z jpa
Szukaj…
Uwagi
JPA to Java Persistence API, specyfikacja obsługująca mapowanie obiektów Java i ich relacji do relacyjnej bazy danych. Nazywa się to mapowaniem obiektowo-relacyjnym (ORM). Jest to alternatywa dla (lub uzupełnienie) JDBC na niższym poziomie. Jest to najbardziej przydatne, gdy stosuje się podejście zorientowane na Javę i gdy trzeba utrwalić złożone wykresy obiektów.
JPA samo w sobie nie jest implementacją. Będziesz potrzebował do tego dostawcy trwałości (patrz przykłady). Obecne implementacje najnowszego standardu JPA 2.1 to EclipseLink (także implementacja referencyjna dla JPA 2.1, co oznacza „dowód, że specyfikacja może zostać zaimplementowana”); Hibernacja i DataNucleus .
Metadane
Odwzorowanie między obiektami Java i tabelami bazy danych jest definiowane za pomocą metadanych trwałości . Dostawca JPA użyje informacji o metadanych trwałości do wykonania prawidłowych operacji na bazie danych. JPA zazwyczaj definiuje metadane za pomocą adnotacji w klasie Java.
Architektura obiektowo-relacyjna
Architektura encji składa się z:
- podmioty
- jednostki uporczywości
- konteksty trwałości
- fabryki podmiotów zarządzających
- menedżerowie podmiotów
Wersje
Instalacja lub konfiguracja
Wymagania dotyczące ścieżki klas
Eclipselink
Należy uwzględnić interfejs Eclipselink i JPA API. Przykładowe zależności Maven:
<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>
Hibernować
Wymagany jest rdzeń hibernacyjny. Przykładowa zależność Maven:
<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
wymagane są rdzeń datanucleus, datanucleus-api-jpa i datanucleus-rdbms (w przypadku korzystania z magazynów danych RDBMS). Przykładowa zależność Maven:
<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>
Szczegóły konfiguracji
JPA wymaga użycia pliku persistence.xml , który znajduje się pod META-INF od katalogu głównego CLASSPATH. Ten plik zawiera definicję dostępnych jednostek trwałości, z których może działać JPA.
JPA dodatkowo pozwala na użycie pliku konfiguracyjnego mapowania orm.xml , również umieszczonego pod META-INF . Ten plik mapowania służy do konfigurowania sposobu mapowania klas do magazynu danych i jest alternatywą / uzupełnieniem do stosowania adnotacji Java w samych klasach jednostek JPA.
Przykład minimalnego persistence.xml
Hibernacja (i osadzona 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 (i osadzony 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 (i osadzony 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>
Witaj świecie
Zobaczmy wszystkie podstawowe elementy do stworzenia prostego świata Hallo.
- Określ, której implementacji JPA 2.1 będziemy używać
- Zbuduj połączenie z bazą danych, tworząc jednostkę
persistence-unit - Implementuje podmioty
- Implementuje DAO (obiekt dostępu do danych) do manipulowania obiektami
- Przetestuj aplikację
Biblioteki
Korzystając z maven, potrzebujemy następujących zależności:
<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>
Jednostka przetrwania
W folderze zasobów musimy utworzyć plik o nazwie persistence.xml . Najłatwiejszym sposobem zdefiniowania tego jest:
<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>
Zaimplementuj encję
Tworzę klasowego 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;
}
}
Wdrożenie 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 to 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;
}
}
Przetestuj aplikację
pakiet it.hello.jpa.test;
TestJpa klasy publicznej {
@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));
}
}
Dane wyjściowe będą:
Uruchamianie it.hello.jpa.test.TestJpa Hibernacja: upuść tabelę BIKER, jeśli istnieje Hibernacja: sekwencja upuszczenia, jeśli istnieje hibernacja_sekwencja Hibernacja: utwórz sekwencję hibernacja_sekwencja zacznij od 1 przyrostu o 1 Hibernacja: utwórz tabelę BIKER (identyfikator nie jest zerowy, bitwa nazwa varchar (255 ), broda boolean, data urodzin, bikerName varchar (255), data rejestracji czas, klucz podstawowy (id)) Hibernacja: zmień tabelę BIKER dodaj ograniczenie UK_a64ce28nywyk8wqrvfkkuapli unikalny (nazwa bitwy) Hibernacja: wstaw do BIKER (nazwa bitwy, broda, urodziny, nazwa rowerzysty, data rejestracji , id) wartości (?,?,?,?,?,?) 01 marca 2017 11:00:02 org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation INFO: HHH000204: Processing PersistenceUnitInfo [nazwa: hello- jpa-pu ...] Wyniki:
Uruchamianie testów: 1, niepowodzenia: 0, błędy: 0, pominięte: 0