Když lidé jsou na JPA, Hibernate nebo EclipseLink, jsou často zmateni o rozdílu mezi nimi, a který z nich by měly používat ve svém projektu. Pokud jste jedním z nich, nebojte se. Je to mnohem jednodušší, než se zdá.
pojďme se nejprve podívat na specifikaci JPA.
Java Persistence API (JPA)
JPA je zkratka, která znamená Java Persistence API. To je specifikace, která je součástí Java EE a definuje API pro objektově-relační mapování a pro správu perzistentních objektů. Toto API můžete použít v prostředí Java SE a Java EE.
SPECIFIKACE je aktuálně k dispozici ve verzi 2.2. Dokument si můžete stáhnout na adrese https://jcp.org/en/jsr/detail?id=338. API jar je k dispozici na následujících souřadnicích Maven:
<dependency> <groupId>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> <version>2.2</version></dependency>
JPA sama o sobě neposkytuje žádné implementační třídy. API jar obsahuje pouze sadu rozhraní, které můžete použít k implementaci vrstvy persistence. Ale nemůžete použít JPA sám. Potřebujete poskytovatele JPA, který implementuje specifikaci. K dispozici je několik možností. Nejoblíbenější jsou hibernace a EclipseLink. Ale o tom později.
až donedávna byla JPA řízena a vyvíjena expertní skupinou v návaznosti na proces Java Community (JCP). To se změnilo, když společnost Oracle oznámila, že převede všechny SPECIFIKACE Java EE do nadace Eclipse Foundation. Nyní jsme uprostřed procesu přechodu a brzy bude definován nový proces SPECIFIKACE.
Jak je definován JPA specifikace
specifikace definuje většinu funkcí, které jsem vysvětlil v návody a videa na tomto webu. Můžete je použít se všemi kompatibilními implementacemi JPA.
pojďme se podívat na některé z nejdůležitějších.
Bootstrapping a základní mapování entit
než začnete používat JPA, musíte jej přidat do projektu, nakonfigurovat jednotku persistence, mapovat entity do databázových tabulek a bootstrap. Pravděpodobně už víte, jak to udělat, a vysvětlil jsem to velmi podrobně v mém článku Začínáme s hibernace.
takže přeskočme tuto část a promluvme si o zajímavějších funkcích.
mapování asociací
JPA vám nejen umožňuje mapovat jednoduché atributy entity do sloupců databáze, ale také umožňuje mapovat přidružení mezi databázovými tabulkami k atributům entity.
@Entitypublic class Review {...@ManyToOneprivate Book book;...}
často je vaše jednotka model velmi pohodlné použití, protože potřebujete jen volat getter metody na entitu načíst související subjekty. Na pozadí poskytovatel persistence provádí všechny požadované databázové operace k načtení a správě přidružení.
jak pohodlné je použití, Tato funkce často způsobuje problémy s výkonem. Než začnete modelovat asociace mezi vašimi entitami, ujistěte se, že rozumíte účinku Fetchtypů JPA, abyste se vyhnuli problémům s výběrem n+1.
Jpql a nativní dotazy
JPA definuje vlastní dotazovací jazyk nazvaný JPQL. Je to podobné SQL, ale umožňuje definovat dotazy založené na mapovaném modelu domény namísto modelu tabulky databáze.
následující úryvek kódu ukazuje jednoduchý dotaz JPQL. Ad-hoc dotaz můžete definovat voláním metody createQuery na EntityManager em. Jak vidíte, syntaxe vypadá velmi podobně jako SQL. Pokud nejste obeznámeni s JPQL, podívejte se prosím na můj průvodce JPQL, ve kterém podrobně vysvětluji jeho syntaxi a možnosti.
TypedQuery<Book> q = em.createQuery("SELECT b FROM Book b WHERE b.id = :id", Book.class);q.setParameter("id", 1L);Book b = q.getSingleResult();
Při spuštění takového dotazu, vaše vytrvalost poskytovatel interpretuje JPQL prohlášení a generuje SQL dotazu. Tímto způsobem poskytovatel persistence přizpůsobí dotaz dialektu SQL specifickému pro databázi a zlepší přenositelnost vaší aplikace.
to vás bohužel také omezuje na funkce dotazu definované specifikací nebo proprietárně podporované poskytovatelem persistence. Tato sada funkcí je výrazně menší než ta, kterou nabízí SQL, a neobsahuje žádné proprietární databázové funkce.
ale to neznamená, že s JPA nemůžete používat žádné pokročilé nebo složité dotazy. Je navržen jako děravá abstrakce a umožňuje provádět nativní SQL dotazy. Ty nejsou analyzovány poskytovatelem persistence, a můžete použít všechny funkce podporované vaší databáze. Mějte však na paměti, že by to mohlo negativně ovlivnit přenositelnost vaší databáze.
provedení nativního dotazu je velmi jednoduché. Stačí zavolat metodu createNativeQuery namísto metody createQuery na EntityManager s nativním dotazem SQL.
Query q = em.createNativeQuery("SELECT * FROM book b WHERE id = :id", Book.class);q.setParameter("id", 1L);Book b = (Book) q.getSingleResult();
Uživatelské Datové Typy
specifikace JPA definuje mapování pro většinu standardních typů bez omezení na ně. Od JPA 2.1 můžete snadno podporovat vlastní datové typy pomocí AttributeConverter. Stačí implementovat rozhraní AttributeConverter a anotovat třídu anotací @Converter.
zde je příklad převaděče atributů, který definuje vlastní mapování pro můj 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 a hibernace
Jak jsem již řekl, potřebujete poskytovatele JPA, pokud chcete ve svém projektu použít specifikaci JPA. Implementuje rozhraní definovaná specifikací. Nejoblíbenější jsou EclipseLink a hibernace.
jednou z výhod standardizovaného API poskytovaného JPA je, že stačí přidat jeho implementaci za běhu a že jej můžete nahradit jiným bez změny kódu. Standardizované API dělá EclipseLink a Hibernate zaměnitelné.
proč tedy potřebujete různé implementace?
implementace JPA jsou řízeny nezávislými týmy a můžete si vybrat ten, který poskytuje nejlepší výkon nebo podporu pro vaši aplikaci a technologii. Odlišují se také poskytováním dalších nestandardních funkcí. To se často používá k podpoře inovací. Dnešní populární, proprietární funkce může být prvním krokem k dalšímu přidání standardu JPA. Použití kterékoli z těchto proprietárních funkcí samozřejmě ztěžuje nahrazení konkrétní implementace JPA.
EclipseLink
EclipseLink je referenční implementace JPA a implementuje JPA verze 2.2. To byl jeden z prvních projektů, který se stal součástí EE4J.
nejjednodušší způsob, jak přidat EclipseLink, aby váš projekt je použít následující Maven souřadnice.
<dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>2.7.1</version></dependency>
Zajímavé proprietární funkce,
kromě funkcí definován standard JPA, EclipseLink také nabízí několik zajímavých, proprietární funkce, jako:
- Zpracování z databáze události změny
- Kompozitní vytrvalost jednotek na mapě subjektů, na tabulkách ve více databázích
- Podpora pro multi-nájemní
režim Spánku
Hibernate je Červený Klobouk je velmi populární implementace JPA specifikace. Implementuje téměř všechny funkce definované JPA 2.2 a brzy vydá plně kompatibilní verzi.
následující závislost Maven přidá hibernaci do vašeho projektu.
<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>5.1.11</version></dependency>
Zajímavé proprietární funkce,
Podobné EclipseLink, Hibernate poskytuje spoustu zajímavých, proprietární funkce, jako je:
- Rozšířená podpora pro přirozené Id
- Vkládání více subjektů prostřednictvím jejich primárních klíčů
- Řízení tvorby a aktualizace časových razítek
- Spojování nespřízněných subjektů na dotazy
- Podpora pro multi-nájemní