amikor az emberek újak a JPA, Hibernate vagy EclipseLink számára, gyakran összekeverik őket a köztük lévő különbséggel és azzal, hogy melyiket használják a projektjükben. Ha közéjük tartozol, ne aggódj. Sokkal könnyebb, mint amilyennek látszik.
vessünk egy pillantást a JPA specifikáció első.
Java Persistence API (JPA)
a JPA a Java Persistence API rövidítése. Ez egy olyan specifikáció, amely a Java EE része, és meghatároz egy API-t az objektum-relációs leképezésekhez és az állandó objektumok kezeléséhez. Ezt az API-t Java SE és Java EE környezetben használhatja.
a specifikáció jelenleg a 2.2-es verzióban érhető el. A dokumentumot a https://jcp.org/en/jsr/detail?id=338címen töltheti le. Az API jar a következő Maven koordinátákon érhető el:
<dependency> <groupId>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> <version>2.2</version></dependency>
maga a JPA nem nyújt implementációs osztályokat. Az API jar csak tartalmaz egy sor interfészek, amelyek segítségével végre a perzisztencia réteg. De önmagában nem használhatja a JPA-t. Szüksége van egy JPA szolgáltatóra, amely megvalósítja a specifikációt. Számos lehetőség áll rendelkezésre. A legnépszerűbbek a Hibernate és az EclipseLink. De erről később.
egészen a közelmúltig a JPA-t egy szakértői csoport irányította és fejlesztette ki a Java Community Process (JCP) után. Ez megváltozott, amikor az Oracle bejelentette, hogy az összes Java EE specifikációt átadja az Eclipse Alapítványnak. Most az átmeneti folyamat közepén vagyunk, és hamarosan egy új specifikációs folyamat kerül meghatározásra.
mi határozza meg a JPA specifikáció
a specifikáció meghatározza a legtöbb olyan funkciót, amelyet az ezen az oldalon található oktatóanyagokban és videókban kifejtettem. Használhatja őket az összes kompatibilis JPA implementációval.
vessünk egy pillantást a legfontosabbakra.
Bootstrapping és alapvető entitásleképezések
mielőtt elkezdené használni a JPA-t, hozzá kell adnia a projekthez, be kell állítania egy perzisztencia egységet, fel kell térképeznie az entitásokat az adatbázis-táblákhoz, és bootstrap-ot kell készítenie. Valószínűleg már tudja, hogyan kell ezt megtenni, és nagyon részletesen elmagyaráztam a Hibernate első lépések című cikkemben.
tehát hagyjuk ki ezt a részt itt, és beszéljünk az érdekesebb funkciókról.
asszociációk leképezése
a JPA nem csak egyszerű entitás-attribútumok adatbázis-oszlopokhoz való leképezését teszi lehetővé, hanem lehetővé teszi az adatbázis-táblák közötti társítások entitásattribútumokhoz való leképezését is.
@Entitypublic class Review {...@ManyToOneprivate Book book;...}
Ez gyakran nagyon kényelmessé teszi az entitásmodell használatát, mert csak egy getter metódust kell hívnia egy entitáson a társított entitások betöltéséhez. A háttérben a perzisztencia szolgáltató elvégzi az összes szükséges adatbázis-műveletet az asszociáció lekéréséhez és kezeléséhez.
bármilyen kényelmes is a használata, ez a funkció gyakran teljesítményproblémákat okoz. Mielőtt elkezdené modellezni az entitások közötti asszociációkat, győződjön meg róla, hogy megértette a JPA FetchTypes hatását az N+1 select problémák elkerülése érdekében.
Jpql és natív lekérdezések
a JPA meghatározza saját lekérdezési nyelvét, az úgynevezett JPQL-t. Hasonló az SQL-hez, de lehetővé teszi a lekérdezések meghatározását a leképezett tartománymodell alapján az adatbázis táblázatmodellje helyett.
a következő kódrészlet egy egyszerű JPQL lekérdezést mutat. Megadhat egy ad-hoc lekérdezést a createQuery metódus meghívásával az EntityManager em-en. Mint látható, a szintaxis nagyon hasonlít az SQL-hez. Ha nem ismeri a JPQL-t, kérjük, vessen egy pillantást a JPQL Útmutatómra, amelyben részletesen elmagyarázom a szintaxisát és képességeit.
TypedQuery<Book> q = em.createQuery("SELECT b FROM Book b WHERE b.id = :id", Book.class);q.setParameter("id", 1L);Book b = q.getSingleResult();
amikor ilyen lekérdezést hajt végre, a perzisztencia szolgáltató értelmezi a JPQL utasítást, és létrehoz egy SQL lekérdezést. Ezzel a perzisztencia szolgáltató adaptálja a lekérdezést az adatbázis-specifikus SQL nyelvjáráshoz, és javítja az alkalmazás hordozhatóságát.
sajnos ez a specifikáció által meghatározott vagy a perzisztencia-szolgáltató által támogatott lekérdezési funkciókra is korlátozza Önt. Ez a funkciókészlet lényegesen kisebb, mint az SQL által kínált, és nem tartalmaz saját adatbázis-funkciókat.
de ez nem jelenti azt, hogy nem használhat speciális vagy összetett lekérdezéseket a JPA-val. Úgy tervezték, mint egy szivárgó absztrakció, és lehetővé teszi, hogy végre natív SQL lekérdezések. Ezeket a perzisztencia-Szolgáltató nem elemzi, és az adatbázis által támogatott összes funkciót használhatja. De kérjük, vegye figyelembe, hogy ez negatívan befolyásolhatja az adatbázis hordozhatóságát.
a natív lekérdezés végrehajtása nagyon egyszerű. Csak meg kell hívnia a createNativeQuery módszert az EntityManager createQuery módszere helyett egy natív SQL lekérdezéssel.
Query q = em.createNativeQuery("SELECT * FROM book b WHERE id = :id", Book.class);q.setParameter("id", 1L);Book b = (Book) q.getSingleResult();
egyéni adattípusok
a JPA specifikáció meghatározza a legtöbb szabványos típus leképezését anélkül, hogy korlátozná őket. Mivel a JPA 2.1, akkor könnyen támogatja az egyéni adattípusok egy AttributeConverter. Csak végre kell hajtania az AttributeConverter felületet, és jegyezze fel az osztályt egy @Converter megjegyzéssel.
íme egy példa egy attribútum-átalakítóra, amely meghatározza a saját AuthorStatus enum egyedi leképezését.
@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 and Hibernate
mint korábban mondtam, szüksége van egy JPA szolgáltatóra, ha a JPA specifikációt szeretné használni a projektben. A specifikációban meghatározott interfészeket valósítja meg. A legnépszerűbbek az EclipseLink és a Hibernate.
a JPA által biztosított szabványosított API egyik előnye, hogy csak hozzá kell adnia a végrehajtását futásidőben, és hogy kicserélheti egy másikra anélkül, hogy bármilyen kódot megváltoztatna. A szabványosított API teszi eclipselink és Hibernate cserélhető.
tehát miért van szükség különböző implementációkra?
a JPA implementációkat független csapatok kezelik, és kiválaszthatja azt, amelyik a legjobb teljesítményt nyújtja, vagy támogatja az alkalmazás-és technológiai veremét. Megkülönböztetik magukat azzal is, hogy további, nem szabványos funkciókat biztosítanak. Ezt gyakran használják az innováció ösztönzésére. A mai népszerű, szabadalmaztatott funkció lehet az első lépés a JPA szabvány következő kiegészítéséhez. Ezen szabadalmaztatott funkciók bármelyikének használata nyilvánvalóan sokkal nehezebbé teszi egy adott JPA megvalósítás helyettesítését.
EclipseLink
az EclipseLink a JPA referencia implementációja és a JPA 2.2-es verzióját valósítja meg. Ez volt az egyik első projekt, amely az EE4J részévé vált.
az EclipseLink hozzáadásának legegyszerűbb módja a következő Maven koordináták használata.
<dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>2.7.1</version></dependency>
érdekes szabadalmaztatott funkciók
a JPA szabvány által meghatározott funkciók mellett az EclipseLink számos érdekes, szabadalmaztatott funkciót is kínál, például:
- Adatbázis-változási események kezelése
- összetett perzisztencia egységek az entitások táblázatokhoz való leképezéséhez több adatbázisban
- a multi-tenancy támogatása
Hibernate
a Hibernate a Red Hat nagyon népszerű megvalósítása a JPA specifikációnak. A JPA 2.2 által meghatározott szinte minden funkciót megvalósítja, és hamarosan kiad egy teljesen kompatibilis verziót.
a következő Maven-függőség hibernálást ad a projekthez.
<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>5.1.11</version></dependency>
érdekes szabadalmaztatott funkciók
az Eclipselinkhez hasonlóan a Hibernate egy csomó érdekes, szabadalmaztatott funkciót kínál, mint például:
- kiterjesztett támogatás a természetes azonosítókhoz
- több entitás betöltése az elsődleges kulcsukkal
- a létrehozás és a frissítés időbélyegeinek kezelése
- csatlakozás a nem társított entitásokhoz a lekérdezésekben
- több bérleti támogatás