Als specificatie houdt de Java Persistence API zich bezig met persistence, wat losjes elk mechanisme betekent waarmee Java-objecten het applicatieproces overleven dat ze heeft gemaakt. Niet alle Java-objecten hoeven te worden voortgezet, maar de meeste toepassingen blijven belangrijke zakelijke objecten. Met de JPA-specificatie kunt u bepalen welke objecten moeten worden persisted, en hoe die objecten moeten worden persisted in uw Java-toepassingen.
op zichzelf is JPA geen gereedschap of raamwerk; integendeel, het definieert een set van concepten die kunnen worden geïmplementeerd door elk instrument of raamwerk. Terwijl JPA ‘ s object-relational mapping (ORM) model oorspronkelijk gebaseerd was op Hibernate, is het sindsdien geëvolueerd. Hoewel JPA oorspronkelijk bedoeld was voor gebruik met relationele/SQL-databases, zijn sommige JPA-implementaties uitgebreid voor gebruik met NoSQL-datastores. Een populair framework dat JPA ondersteunt met NoSQL is EclipseLink, de referentie implementatie voor JPA 2.2.
JPA en Hibernate
vanwege hun verweven geschiedenis worden Hibernate en JPA vaak met elkaar verbonden. Echter, net als de Java Servlet specificatie, JPA heeft voortgebracht vele compatibele tools en frameworks; Hibernate is slechts een van hen.Hibernate, ontwikkeld door Gavin King en uitgebracht in 2002, is een ORM-bibliotheek voor Java. King ontwikkelde Hibernate als een alternatief voor entiteit bonen voor persistentie. Het kader was destijds zo populair en zo nodig dat veel van de ideeën ervan in de eerste specificatie van de PPV werden overgenomen en gecodificeerd.
vandaag de dag is Hibernate ORM een van de meest volwassen JPA-implementaties, en nog steeds een populaire optie voor ORM in Java. Winterslaap ORM 5.3.8 (de huidige versie van dit schrijven) implementeert JPA 2.2. Bovendien, Hibernate ‘ s familie van tools is uitgebreid met populaire tools zoals Hibernate Search omvatten, Hibernate Validator, en Hibernate OGM, die domein-model persistentie ondersteunt voor NoSQL.
Wat is Java ORM?
hoewel ze verschillen in uitvoering, biedt elke JPA-implementatie een soort ORM-laag. Om JPA en JPA-compatibele tools te begrijpen, moet je een goede greep op ORM hebben.
Object-relationele toewijzing is een taak die ontwikkelaars goede redenen hebben om handmatig te vermijden. Een raamwerk zoals Hibernate ORM of EclipseLink codificeert die taak in een bibliotheek of raamwerk, een ORM-laag. Als onderdeel van de applicatiearchitectuur is de Orm-laag verantwoordelijk voor het beheren van de conversie van softwareobjecten om te interageren met de tabellen en kolommen in een relationele database. In Java, de Orm laag converteert Java klassen en objecten, zodat ze kunnen worden opgeslagen en beheerd in een relationele database.
standaard wordt de naam van het object dat wordt aangehouden De naam van de tabel en worden velden kolommen. Zodra de tabel is ingesteld, komt elke tabelrij overeen met een object in de toepassing. Object mapping is configureerbaar, maar standaardwaarden werken meestal goed.
figuur 1 illustreert de rol van JPA en de Orm-laag bij de ontwikkeling van toepassingen.
het instellen van de Java ORM-laag
wanneer u een nieuw project opzet om JPA te gebruiken, moet u de datastore en JPA provider configureren. U configureert een datastore-connector om verbinding te maken met de door u gekozen database (SQL of NoSQL). Je zult ook de JPA provider opnemen en configureren, wat een framework is zoals Hibernate of EclipseLink. Hoewel u JPA handmatig kunt configureren, kiezen veel ontwikkelaars ervoor om de out-of-the-box ondersteuning van Spring te gebruiken. Zie” JPA installatie en setup ” hieronder voor een demonstratie van zowel handmatige als Veergebaseerde JPA installatie en setup.
data persistence in Java
vanuit een programmeerperspectief is de Orm-laag een adapterlaag: het past de taal van objectgrafieken aan de taal van SQL en relationele tabellen aan. De ORM-laag stelt object-georiënteerde ontwikkelaars in staat om software te bouwen die gegevens blijft bestaan zonder ooit het object-georiënteerde paradigma te verlaten.
wanneer u JPA gebruikt, maakt u een toewijzing van de datastore naar de datamodelobjecten van uw toepassing. In plaats van te definiëren hoe objecten worden opgeslagen en opgehaald, definieert u de toewijzing tussen objecten en uw database en roept u vervolgens JPA aan om ze te laten voortduren. Als je een relationele database gebruikt, zal een groot deel van de daadwerkelijke verbinding tussen je applicatie code en de database worden afgehandeld door JDBC, de Java Database Connectivity API.
als spec biedt JPA metadata-annotaties, die u gebruikt om de toewijzing tussen objecten en de database te definiëren. Elke JPA-implementatie biedt zijn eigen motor voor JPA-annotaties. De JPA-specificatie biedt ook de PersistanceManager
of EntityManager
, die de belangrijkste contactpunten zijn met het JPA-systeem (waarin uw business logic code het systeem vertelt wat te doen met de toegewezen objecten).
om dit alles concreter te maken, overweeg Listing 1, wat een eenvoudige dataklasse is voor het modelleren van een muzikant.
Lijst 1. Een eenvoudige gegevensklasse in Java
de Musician
klasse in Lijst 1 wordt gebruikt om gegevens vast te houden. Het kan primitieve gegevens bevatten, zoals het veld Naam. Het kan ook relaties houden met andere klassen, zoals mainInstrument
en performances
.
Musician
’s reden voor zijn is om gegevens te bevatten. Dit type klasse wordt ook wel DTO of data transfer object genoemd. DTO ‘ s zijn een gemeenschappelijk kenmerk van softwareontwikkeling. Hoewel ze veel soorten gegevens bevatten, bevatten ze geen zakelijke logica. Persisting Data objects is een alomtegenwoordige uitdaging in softwareontwikkeling.
persistentie van gegevens met JDBC
een manier om een instantie van de Musician
klasse op te slaan in een relationele database zou zijn om de JDBC-bibliotheek te gebruiken. JDBC is een laag van abstractie die een applicatie probleem SQL commando ‘ s laat zonder na te denken over de onderliggende database implementatie.
Listing 2 laat zien hoe u deMusician
Klasse kunt aanhouden met behulp van JDBC.
Lijst 2. JDBC het invoegen van een record
de code in lijst 2 is vrij zelfdocumenterend. HetgeorgeHarrison
object kan overal vandaan komen (front-end submit, external service, etc.), en heeft zijn ID en naam velden ingesteld. De velden op het object worden dan gebruikt om de waarden van een SQL insert
statement te geven. (DePreparedStatement
klasse maakt deel uit van JDBC en biedt een manier om veilig waarden toe te passen op een SQL query.)
terwijl JDBC de controle die wordt geleverd met handmatige configuratie toestaat, is het omslachtig in vergelijking met JPA. Om de database te wijzigen, moet u eerst een SQL-query maken die van uw Java-object wordt toegewezen aan de tabellen in een relationele database. Je moet dan de SQL aanpassen wanneer een object handtekening verandert. Met JDBC wordt het onderhouden van de SQL een taak op zich.
persistentie van gegevens met JPA
overweeg nu om 3 op te nemen, waarbij we de Musician
klasse aanhouden met behulp van JPA.
Listing 3. Persisting George Harrison with JPA
Musician georgeHarrison = new Musician(0, "George Harrison");musicianManager.save(georgeHarrison);
Listing 3 vervangt de handmatige SQL van Listing 2 door een enkele regel, session.save()
, die JPA instrueert om het object aan te houden. Vanaf dat moment wordt de SQL conversie afgehandeld door het framework, zodat je nooit het object-georiënteerde paradigma hoeft te verlaten.
metadata annotaties in JPA
De magie in Lijst 3 is het resultaat van een configuratie, die wordt gemaakt met behulp van JPA ‘ s annotaties. Ontwikkelaars gebruiken annotaties om JPA te informeren welke objecten moeten worden gecontinueerd, en hoe ze moeten worden gecontinueerd.
Listing 4 toont deMusician
klasse met een enkele JPA-annotatie.
lijst 4. JPA ‘ s @Entity annotation
@Entitypublic class Musician { // ..class body}
persistente objecten worden soms entiteiten genoemd. Het koppelen van @Entity
aan een klasse als Musician
informeert JPA dat deze klasse en zijn objecten moeten worden gehandhaafd.
Configuring JPA
zoals de meeste moderne frameworks, omvat JPA codering volgens conventie (ook bekend als Conventie over configuratie), waarin het framework een standaardconfiguratie biedt op basis van beste praktijken in de industrie. Een voorbeeld: een klasse met de naam Musician
wordt standaard toegewezen aan een databasetabel genaamd musicus.
de conventionele configuratie is een tijdsbesparing, en in veel gevallen werkt het goed genoeg. Het is ook mogelijk om uw JPA configuratie aan te passen. Als voorbeeld kunt u JPA ‘ s @Table
annotatie gebruiken om de tabel te specificeren waar de Musician
klasse moet worden opgeslagen.
lijst 5. JPA ’s @Table annotation
@Entity@Table(name="musician")public class Musician { // ..class body}
Listing 5 vertelt JPA om de entiteit (Musician
klasse) door te zetten naar de musician
tabel.
primaire sleutel
in JPA is de primaire sleutel het veld dat wordt gebruikt om elk object in de database uniek te identificeren. De primaire sleutel is nuttig voor het verwijzen naar en relateren van objecten aan andere entiteiten. Wanneer u een object in een tabel opslaat, geeft u ook het veld op dat als primaire sleutel moet worden gebruikt.
In Lijst 6 vertellen we JPA welk veld te gebruiken als Musician
’s primaire sleutel.
Lijst 6. Het specificeren van de primaire sleutel
@Entitypublic class Musician { @Id private Long id;
in dit geval hebben we JPA’s @Id
annotatie gebruikt om het id
veld op te geven als Musician
‘ s primaire sleutel. Standaard gaat deze configuratie ervan uit dat de primaire sleutel wordt ingesteld door de database-bijvoorbeeld, wanneer het veld is ingesteld op auto-increment op de tabel.
JPA ondersteunt andere strategieën voor het genereren van de primaire sleutel van een object. Het heeft ook annotaties voor het wijzigen van individuele veldnamen. Over het algemeen is JPA flexibel genoeg om zich aan te passen aan elke persistence mapping die je nodig zou kunnen hebben.
CRUD operations
zodra u een klasse aan een databasetabel hebt toegewezen en de primaire sleutel hebt ingesteld, hebt u alles wat u nodig hebt om die klasse aan te maken, op te halen, te verwijderen en bij te werken in de database. Het aanroepen van session.save()
zal de opgegeven klasse aanmaken of bijwerken, afhankelijk van of het primaire sleutelveld null is of Van toepassing is op een bestaande entiteit. Het aanroepen van entityManager.remove()
zal de opgegeven klasse verwijderen.
entiteitsrelaties in JPA
het gewoon aanhouden van een object met een primitief veld is slechts de helft van de vergelijking. De PPV heeft ook de mogelijkheid om entiteiten ten opzichte van elkaar te beheren. Vier soorten entiteitsrelaties zijn mogelijk in zowel tabellen als objecten:
- One-to-many
- Many-To-one
- Many-to-many
- One-to-one
- One-to-many: Lazy
- Many-To-One: Eager
- many-to-many: Lazy
- One-to-one: Eager
elk type relatie beschrijft hoe een entiteit zich verhoudt tot andere entiteiten. De entiteit Musician
kan bijvoorbeeld een één-op-veel relatie hebben met Performance
, een entiteit die wordt vertegenwoordigd door een verzameling zoals List
of Set
.
indien in het Musician
een Band
veld was opgenomen, zou de relatie tussen deze entiteiten veel-op-één kunnen zijn, wat inhoudt dat Musician
s op de enkelvoudige Band
s moet worden verzameld. (Ervan uitgaande dat elke muzikant slechts in een enkele band optreedt.)
indien Musician
een BandMates
veld bevat, dat een veel-tot-veel relatie met andere Musician
entiteiten kan vertegenwoordigen.
ten slotte kan Musician
een één-op-één relatie hebben met een Quote
entiteit, gebruikt om een beroemd citaat weer te geven: Quote famousQuote = new Quote()
.
Defining relationship types
JPA heeft annotaties voor elk van zijn relationship mapping types. Listing 7 laat zien hoe u de een-op-veel relatie tussen Musician
en Performance
s.
Listing 7 kunt annoteren. Annoteren van een een-op-veel relatie
een ding om op te merken is dat de @JoinColumn
vertelt JPA welke kolom op de Prestatietabel zal toewijzen aan de Musician
entiteit. Elke prestatie wordt gekoppeld aan één enkele Musician
, die door deze kolom wordt gevolgd. Wanneer JPA een Musician
of een Performance
in de database laadt, zal het deze informatie gebruiken om de objectgrafiek opnieuw samen te stellen.
Fetching strategies in JPA
naast het weten waar gerelateerde entiteiten in de database moeten worden geplaatst, moet JPA weten hoe u ze wilt laden. Ophalen strategieën vertellen JPA hoe gerelateerde entiteiten te laden. Bij het laden en opslaan van objecten, moet een JPA framework de mogelijkheid bieden om te finetune hoe object grafieken worden behandeld. Bijvoorbeeld, als de Musician
klasse een bandMate
veld heeft (zoals weergegeven in Lijst 7), kan het laden van george
ertoe leiden dat de gehele Muzikantentabel uit de database wordt geladen!
wat nodig is, is de mogelijkheid om lazy loading van verwante entiteiten te definiëren–waarbij natuurlijk wordt erkend dat relaties in PPA gretig of lui kunnen zijn. U kunt annotaties gebruiken om uw fetching strategieën aan te passen, maar de standaard configuratie van JPA werkt vaak uit de doos, zonder wijzigingen:
JPA installatie en setup
We sluiten af met een snelle blik op Installeren en instellen JPA voor uw Java-toepassingen. Voor deze demonstratie gebruik ik EclipseLink, de JPA referentie implementatie.
de gebruikelijke manier om JPA te installeren is door een JPA-provider in uw project op te nemen. Lijst 8 laat zien hoe u EclipseLink als een afhankelijkheid zou opnemen in uw Maven pom.xml
bestand.
lijst 8. EclipseLink Include as a Maven dependency
org.eclipse.persistenceeclipselink2.5.0-RC1
u moet ook het stuurprogramma voor uw database opnemen, zoals weergegeven in lijst 9.
lijst 9. Maven dependency voor een MySQL connector
mysqlmysql-connector-java5.1.32
vervolgens moet u het systeem vertellen over uw database en provider. Dit wordt gedaan in het persistence.xml
bestand, zoals weergegeven in Lijst 10.
Lijst 10. Persistentie.xml
Er zijn andere manieren om deze informatie aan het systeem te verstrekken, inclusief programmatisch. Ik raad aan om het persistence.xml
bestand te gebruiken omdat het opslaan van afhankelijkheden op deze manier het zeer eenvoudig maakt om uw applicatie bij te werken zonder de code te wijzigen.
Spring configuratie voor JPA
het gebruik van Spring zal de integratie van JPA in uw applicatie aanzienlijk vergemakkelijken. Als voorbeeld, het plaatsen van de @SpringBootApplication
annotatie in uw toepassingskop instrueert Spring om automatisch te scannen naar klassen en de EntityManager
te injecteren zoals vereist, gebaseerd op de configuratie die u hebt opgegeven.
Listing 11 toont de afhankelijkheden die moeten worden opgenomen als u de JPA-ondersteuning van Spring voor uw toepassing wilt.
lijst 11. Het toevoegen van Spring JPA-ondersteuning in Maven
conclusie
elke toepassing die zich bezighoudt met een database moet een applicatielaag definiëren waarvan het enige doel is om persistentiecode te isoleren. Zoals je hebt gezien in dit artikel, de Java Persistence API introduceert een scala aan mogelijkheden en ondersteuning voor Java object persistence. Eenvoudige toepassingen vereisen mogelijk niet alle mogelijkheden van JPA, en in sommige gevallen is de overhead van het configureren van het framework misschien niet verdiend. Naarmate een applicatie groeit, echter, JPA structuur en inkapseling echt verdienen hun keep. Met behulp van JPA houdt uw object code eenvoudig en biedt een conventioneel kader voor de toegang tot gegevens in Java-toepassingen.
meer informatie over de Java Persistence API en gerelateerde technologieën
- Wat is JDBC? Inleiding tot Java Database connectiviteit: Maak kennis met Java ’s low-level API voor het verbinden met een database, het uitgeven van SQL query’ s, en meer.
- Java persistence with JPA and Hibernate, Part 1: Entities and relationships: Get started modeling entities and relationships with Java 8 and Hibernate ORM.
- Java-persistentie met JPA en Hibernate, deel 2: Hands-on praktijk modelleren veel-tot-veel relaties en erfenis relaties in Java 8 en overwinteren ORM.
- implementatie van status-afhankelijk gedrag: een klassieke introductie tot het status patroon en status afhankelijkheid in Java.
- Eager / Lazy Loading In Hibernate: hoe u eager en lazy loading in Hibernate toepast.
- JPA 2.2 brengt enkele langverwachte wijzigingen: een overzicht van specificatie-updates in JPA 2.2, inclusief verbeteringen aan CDI, betere afstemming met de datum en tijd API, en ondersteuning voor
@Repeatable
annotaties. - moet u JPA gebruiken voor uw volgende project?: Belangrijke vragen die u kunnen helpen beslissen.