Vad är skillnaden mellan JPA, Hibernate och EclipseLink

När människor är nya för JPA, Hibernate eller EclipseLink är de ofta förvirrade över skillnaden mellan dem och vilken de ska använda i sitt projekt. Om du är en av dem, oroa dig inte. Det är mycket lättare än det verkar.

Låt oss ta en titt på JPA-specifikationen först.

Java Persistence API (JPA)

JPA är en förkortning som står för Java Persistence API. Det är en specifikation som ingår i Java EE och definierar ett API för objektrelationella mappningar och för hantering av beständiga objekt. Du kan använda detta API i Java SE och Java EE miljöer.

specifikationen finns för närvarande i version 2.2. Du kan ladda ner dokumentet på https://jcp.org/en/jsr/detail?id=338. API-burken finns på följande Maven-koordinater:

<dependency> <groupId>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> <version>2.2</version></dependency>

JPA själv tillhandahåller inga implementeringsklasser. API-burken innehåller bara en uppsättning gränssnitt som du kan använda för att implementera ditt persistenslager. Men du kan inte använda JPA på egen hand. Du behöver en JPA-leverantör som implementerar specifikationen. Det finns flera alternativ tillgängliga. De mest populära är Hibernate och EclipseLink. Men mer om det senare.

fram till nyligen har JPA hanterats och utvecklats av en expertgrupp som följer Java Community Process (JCP). Det förändrades när Oracle meddelade att överföra alla Java EE-SPECIFIKATIONER till Eclipse Foundation. Vi är nu mitt i övergångsprocessen, och en ny specifikationsprocess kommer snart att definieras.

vad definieras av JPA-specifikationen

specifikationen definierar de flesta funktioner som jag förklarade i tutorials och videor på den här webbplatsen. Du kan använda dem med alla kompatibla JPA-implementeringar.

Låt oss ta en titt på några av de viktigaste.

Bootstrapping och basic entity mappings

innan du kan börja använda JPA måste du lägga till det i ditt projekt, konfigurera en persistensenhet, kartlägga enheter i dina databastabeller och starta upp det. Du vet förmodligen redan hur man gör det, och jag förklarade det i detalj i min Komma igång med Hibernate artikel.

Så, låt oss hoppa över den här delen här och prata om de mer intressanta funktionerna.

Mapping Associations

JPA gör det inte bara möjligt för dig att mappa enkla entitetsattribut till databaskolumner, men det låter dig också mappa associationer mellan databastabeller till entitetsattribut.

@Entitypublic class Review {...@ManyToOneprivate Book book;...}

som ofta gör din enhetsmodell mycket bekväm att använda eftersom du bara behöver ringa en getter-metod på en enhet för att ladda de associerade enheterna. I bakgrunden utför persistence provider alla nödvändiga databasoperationer för att hämta och hantera föreningen.

så bekväm att använda som det kan vara, orsakar dessa funktioner ofta prestandaproblem. Innan du börjar modellera associationer mellan dina enheter, se till att du förstår effekten av JPA: s FetchTypes för att undvika n+1 select-problem.

JPQL och Native Queries

JPA definierar sitt eget frågespråk, kallat JPQL. Det liknar SQL men låter dig definiera frågor baserat på den mappade domänmodellen istället för databasens tabellmodell.

följande kodavsnitt visar en enkel JPQL-fråga. Du kan definiera en ad hoc-fråga genom att anropa metoden createQuery på EntityManager em. Som du kan se ser syntaxen mycket ut som SQL. Om du inte är bekant med JPQL, ta en titt på min Jpql-Guide där jag förklarar dess syntax och funktioner i stora detaljer.

TypedQuery<Book> q = em.createQuery("SELECT b FROM Book b WHERE b.id = :id", Book.class);q.setParameter("id", 1L);Book b = q.getSingleResult();

När du kör en sådan fråga tolkar din persistensleverantör jpql-uttalandet och genererar en SQL-fråga för den. Genom att göra det anpassar persistence-leverantören frågan till den databasspecifika SQL-dialekten och förbättrar portabiliteten för din applikation.

tyvärr begränsar det dig också till de frågefunktioner som definieras av specifikationen eller som stöds av din persistensleverantör. Denna funktionsuppsättning är betydligt mindre än den som erbjuds av SQL och innehåller inga egna databasfunktioner.

men det betyder inte att du inte kan använda några avancerade eller komplexa frågor med JPA. Den är utformad som en läckande abstraktion och låter dig köra inbyggda SQL-frågor. Dessa analyseras inte av din persistensleverantör, och du kan använda alla funktioner som stöds av din databas. Men var medveten om att detta kan påverka din databasportabilitet negativt.

att köra en inbyggd fråga är ganska enkelt. Du behöver bara ringa createquery-metoden istället för createQuery-metoden på din EntityManager med en inbyggd SQL-fråga.

Query q = em.createNativeQuery("SELECT * FROM book b WHERE id = :id", Book.class);q.setParameter("id", 1L);Book b = (Book) q.getSingleResult();

anpassade datatyper

JPA-specifikationen definierar mappningen för de flesta standardtyper utan att begränsa dig till dem. Sedan JPA 2.1 kan du enkelt stödja anpassade datatyper med en AttributeConverter. Du behöver bara implementera AttributeConverter-gränssnittet och kommentera klassen med en @Converter-anteckning.

Här är ett exempel på en attributomvandlare som definierar en anpassad mappning för min AuthorStatus enum.

@Converter(autoApply = true)public class AuthorStatusConverter implements AttributeConverter<AuthorStatus, String> {Logger log = Logger.getLogger(AuthorStatusConverter.class.getSimpleName());@Overridepublic String convertToDatabaseColumn(AuthorStatus status) {switch (status) {case NOT_PUBLISHED:logDbConversion(status, "N");return "N";case PUBLISHED:logDbConversion(status, "P");return "P";case SELF_PUBLISHED:logDbConversion(status, "S");return "S";default:throw new IllegalArgumentException("AuthorStatus not supported.");}}@Overridepublic AuthorStatus convertToEntityAttribute(String dbData) {switch (dbData) {case "N":logEntityConversion(AuthorStatus.NOT_PUBLISHED, "N");return AuthorStatus.NOT_PUBLISHED;case "P":logEntityConversion(AuthorStatus.PUBLISHED, "P");return AuthorStatus.PUBLISHED;case "S":logEntityConversion(AuthorStatus.SELF_PUBLISHED, "S");return AuthorStatus.SELF_PUBLISHED;default:throw new IllegalArgumentException("AuthorStatus not supported.");}}private void logDbConversion(AuthorStatus status, String dbData) {log.debug("Convert AuthorStatus enum to .");}private void logEntityConversion(AuthorStatus status, String dbData) {log.debug("Convert DB value to AuthorStatus enum .");}}

EclipseLink och Hibernate

som jag sa tidigare behöver du en JPA-leverantör om du vill använda JPA-specifikationen i ditt projekt. Den implementerar gränssnitten enligt definitionen i specifikationen. De mest populära är EclipseLink och Hibernate.

en fördel med det standardiserade API som tillhandahålls av JPA är att du bara behöver lägga till dess implementering vid körning och att du kan ersätta den med en annan utan att ändra någon kod. Det standardiserade API: et gör EclipseLink och Hibernate utbytbara.

så, varför behöver du olika implementeringar?

JPA-implementeringarna hanteras av oberoende team, och du kan välja den som ger bästa prestanda eller stöd för din applikations-och teknikstack. De skiljer sig också genom att tillhandahålla ytterligare, icke-standardiserade funktioner. Detta används ofta för att driva innovation. Dagens populära, egenutvecklade funktion kan vara det första steget till nästa tillägg till JPA-standarden. Att använda någon av dessa proprietära funktioner gör det självklart mycket svårare att ersätta en specifik JPA-implementering.

EclipseLink

EclipseLink är JPA: s referensimplementering och implementerar JPA version 2.2. Det var ett av de första projekten som blev en del av EE4J.

det enklaste sättet att lägga till EclipseLink i ditt projekt är att använda följande Maven-koordinater.

<dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>2.7.1</version></dependency>

intressanta proprietära funktioner

förutom de funktioner som definieras av JPA-standarden erbjuder EclipseLink också flera intressanta, proprietära funktioner, som:

  • hantering av databasändringshändelser
  • sammansatta persistensenheter för att kartlägga enheter till tabeller i flera databaser
  • stöd för flera hyresgäster

Hibernate

Hibernate är Red Hat: s mycket populära implementering av JPA-specifikationen. Den implementerar nästan alla funktioner som definieras av JPA 2.2 och kommer snart att släppa en helt kompatibel version.

följande Maven-beroende lägger till viloläge i ditt projekt.

<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>5.1.11</version></dependency>

intressanta proprietära funktioner

I likhet med EclipseLink ger Hibernate en massa intressanta, proprietära funktioner, som:

  • Utökat stöd för naturliga ID
  • laddar flera enheter med sin primära nyckel
  • hantering av skapande och uppdateringstidsstämplar
  • gå med i icke-associerade enheter i frågor
  • stöd för flerbostadshus

Lämna ett svar

Din e-postadress kommer inte publiceras.