Java noturības API (JPA) ir Java specifikācija, kas pārvar plaisu starp relāciju datu bāzēm un objektorientētu programmēšanu. Šī divu daļu apmācība iepazīstina ar JPA un paskaidro, kā Java objekti tiek modelēti kā JPA entītijas, kā tiek definētas entītiju attiecības un kā izmantot JPA EntityManager
ar Java krātuves modeli jūsu Java lietojumprogrammās.
Ņemiet vērā, ka šajā apmācībā hibernācija tiek izmantota kā JPA nodrošinātājs. Lielāko daļu jēdzienu var attiecināt arī uz citiem Java noturības ietvariem.
Kas ir JPA?
Lai uzzinātu par JPA un ar to saistīto sistēmu, tostarp EJB 3.0, evolūciju, skatiet sadaļu "Kas ir JPA? Ievads Java Persistence API". un JDBC.
Objektu attiecības JPA
Relāciju datubāzes kā līdzeklis programmu datu glabāšanai pastāv jau kopš pagājušā gadsimta 70. gadiem. Kaut arī izstrādātājiem mūsdienās ir daudz alternatīvu relāciju datu bāzei, šāda veida datu bāzes ir mērogojamas un labi saprotamas, un joprojām tiek plaši izmantotas maza un liela mēroga programmatūras izstrādē.
Java objekti relāciju datu bāzes kontekstā tiek definēti kā vienības. Entītijas tiek izvietotas tabulās, kur tās aizņem kolonnas un rindas. Programmētāji izmanto svešas atslēgas un pievienoties galdiem lai noteiktu attiecības starp entītijām - proti, “viens pret vienu”, “viens pret daudziem” un “daudzi pret daudziem”. Mēs varam arī izmantot SQL (strukturēta vaicājumu valoda), lai izgūtu un mijiedarbotos ar datiem atsevišķās tabulās un vairākās tabulās, izmantojot ārvalstu atslēgu ierobežojumus. Relāciju modelis nav precīzs, taču izstrādātāji var rakstīt vaicājumus, lai izgūtu datus un konstruētu objektus no šiem datiem.
Objektu un attiecību pretestības neatbilstība
Jums var būt pazīstams šis termins objektu un attiecību pretestības neatbilstība, kas attiecas uz izaicinājumu datu objektus kartēt ar relāciju datu bāzi. Šī neatbilstība rodas tāpēc, ka objektorientētais dizains neaprobežojas tikai ar attiecībām viens pret vienu, viens pret daudziem un no daudziem uz daudziem. Tā vietā objektorientētā dizainā mēs domājam par objektiem, to atribūtiem un uzvedību, kā arī par to, kā objekti ir saistīti. Divi piemēri ir iekapsulēšana un mantošana:
- Ja objektā ir cits objekts, mēs to definējam caur iekapsulēšana--a ir attiecības.
- Ja objekts ir cita objekta specializācija, mēs to definējam caur mantojums--an ir attiecības.
Asociācija, apkopošana, kompozīcija, abstrakcija, vispārināšana, realizācija un atkarības ir visas objektorientētās programmēšanas koncepcijas, kuras var būt sarežģīti piesaistīt relāciju modelim.
ORM: Objekta relāciju kartēšana
Neatbilstība starp objektorientēto dizainu un relāciju datu bāzes modelēšanu ir novedusi pie instrumentu klases, kas izstrādāta tieši objektu-relāciju kartēšanai (ORM). ORM rīki, piemēram, Hibernate, EclipseLink un iBatis, relāciju datu bāzes modeļus, ieskaitot entītijas un to attiecības, tulko objektorientētos modeļos. Daudzi no šiem rīkiem pastāvēja pirms JPA specifikācijas, taču bez standarta to funkcijas bija atkarīgas no piegādātāja.
Pirmo reizi EJB 3.0 ietvaros izlaista 2006. gadā, Java Noturības API (JPA) piedāvā standarta veidu, kā objektus anotēt, lai tos varētu kartēt un saglabāt relāciju datu bāzē. Specifikācija nosaka arī kopēju konstrukciju mijiedarbībai ar datu bāzēm. ORM standarta Java lietošana nodrošina konsekvenci pārdevēju ieviešanā, vienlaikus ļaujot arī elastīgi un pievienojumprogrammām. Piemēram, lai gan sākotnējā JPA specifikācija ir piemērojama relāciju datu bāzēm, daži piegādātāju ieviešanas gadījumi ir paplašinājuši JPA lietošanai ar NoSQL datu bāzēm.
JPA attīstība
Pirmais JPA izlaidums, versija 1.0, tika publicēts 2006. gadā, izmantojot Java kopienas procesu (JCP) kā Java specifikācijas pieprasījumu (JSR) 220. Versija 2.0 (JSR 317) tika publicēta 2009. gadā, versija 2.1 (JSR 338) 2013. gadā, un versija 2.2 (JSR 338 apkopes izlaidums) tika publicēta 2017. gadā. JPA 2.2 ir izvēlēta iekļaušanai un pastāvīgai attīstībai Džakartas EE.
Darba sākšana ar JPA
Java noturības API ir specifikācija, nevis ieviešana: tā nosaka izplatītu abstrakciju, kuru var izmantot savā kodā, lai mijiedarbotos ar ORM produktiem. Šajā sadaļā ir apskatītas dažas svarīgas APA specifikācijas daļas.
Jūs uzzināsiet, kā:
- Datubāzē definējiet entītijas, laukus un primārās atslēgas.
- Izveidojiet attiecības starp entītijām datu bāzē.
- Darbs ar
EntityManager
un tās metodes.
Definējot entītijas
Lai definētu entītiju, jums jāizveido klase, kas ir anotēta ar @Entity
anotācija. The @Entity
anotācija ir a marķiera anotācija, ko izmanto, lai atklātu pastāvīgas entītijas. Piemēram, ja vēlaties izveidot grāmatas entītiju, jūs to anotētu šādi:
@Entity publiskās klases grāmata {...}
Pēc noklusējuma šī entītija tiks kartēta Grāmata
tabula, ko nosaka dots klases nosaukums. Ja vēlaties kartēt šo entītiju uz citu tabulu (un pēc izvēles arī noteiktu shēmu), varat izmantot @Tabula
anotācija to darīt. Lūk, kā jūs kartētu Grāmata
klase pie GRĀMATU tabulas:
@Entity @Table (name = "GRĀMATAS") publiskās klases grāmata {...}
Ja tabula GRĀMATAS atradās shēmā PUBLISHING, shēmu varētu pievienot @Tabula
anotācija:
@Table (nosaukums = "GRĀMATAS", shēma = "PUBLICĒŠANA")
Lauku kartēšana kolonnās
Kad entītija ir kartēta uz tabulu, nākamais uzdevums ir definēt tās laukus. Lauki ir definēti kā dalībnieku mainīgie klasē, katra lauka nosaukums tiek piesaistīts tabulas kolonnas nosaukumam. Varat ignorēt šo noklusējuma kartēšanu, izmantojot @Kolonna
anotācija, kā parādīts šeit:
@Entity @Table (name = "BOOKS") public class Book {private String name; @Column (name = "ISBN_NUMBER") privātā virkne isbn; ...}
Šajā piemērā mēs esam pieņēmuši noklusējuma kartēšanu nosaukums
atribūtu, bet norādījis pielāgotu kartēšanu isbn
atribūts. The nosaukums
atribūts tiks kartēts ar nosaukums kolonnu, bet isbn
atribūts tiks kartēts kolonnā ISBN_NUMBER.
The @Kolonna
anotācija ļauj mums definēt lauka / kolonnas papildu īpašības, ieskaitot garumu, vai tas ir nederīgs, vai tam jābūt unikālam, tā precizitātei un mērogam (ja tā ir decimālvērtība), vai tas ir ievietojams un atjaunināms utt.
Norādot primāro atslēgu
Viena no relāciju datu bāzes tabulas prasībām ir tā, lai tajā būtu a primārā atslēgavai atslēga, kas unikāli identificē noteiktu rindu datu bāzē. JPA mēs izmantojam @Id
anotācija, lai lauku norādītu par tabulas galveno atslēgu. Primārajai atslēgai ir jābūt Java primitīva tipa, primitīva iesaiņotāja, piemēram, Vesels skaitlis
vai Garš
, a Stīga
, a Datums
, a BigInteger
vai a BigDecimal
.
Šajā piemērā mēs kartējam id
atribūts, kas ir Vesels skaitlis
, uz tabulas GRĀMATAS kolonnu ID:
@Entity @Table (name = "GRĀMATAS") publiskās klases grāmata {@Id private Integer id; privāts virknes nosaukums; @Column (name = "ISBN_NUMBER") privātā virkne isbn; ...}
Ir iespējams arī apvienot @Id
anotācija ar @Kolonna
anotācija, lai pārrakstītu primārās atslēgas kolonnas nosaukuma kartēšanu.
Attiecības starp entītijām
Tagad, kad jūs zināt, kā definēt entītiju, apskatīsim, kā izveidot attiecības starp entītijām. APA definē četras anotācijas entītiju definēšanai:
@OneToOne
@OneToMany
@ManyToOne
@ManyToMany
Individuālas attiecības
The @OneToOne
anotāciju izmanto, lai definētu savstarpēju attiecību starp divām entītijām. Piemēram, jums var būt Lietotājs
entītija, kurā ir lietotāja vārds, e-pasts un parole, taču jūs varat saglabāt atsevišķu informāciju par lietotāju (piemēram, vecumu, dzimumu un iecienītāko krāsu) Lietotāja profils
vienība. The @OneToOne
anotācija šādā veidā atvieglo jūsu datu un entītiju sadalīšanu.
The Lietotājs
zemāk esošajai klasei ir viens Lietotāja profils
instancē. The Lietotāja profils
kartes vienā Lietotājs
instancē.
@Entity publiskās klases lietotāja {@Id private Integer id; privāta virkne e-pasts; privāts virknes nosaukums; privāta virknes parole; @OneToOne (mappedBy = "user") privātais UserProfile profils; ...}
@Entity publiskā klase UserProfile {@Id private Integer id; privāts int vecums; privāts Stīgu dzimums; privāta virkne favoriteColor; @OneToOne privāts Lietotāja lietotājs; ...}
JPA nodrošinātājs izmanto Lietotāja profils
's lietotājs
karte Lietotāja profils
uz Lietotājs
. Kartēšana ir norādīta kartētsPēc
atribūts @OneToOne
anotācija.
Attiecības "viens pret daudziem" un "viens pret vienu"
The @OneToMany
un @ManyToOne
anotācijas atvieglo abu attiecību abas puses. Apsveriet piemēru, kur a Grāmata
var būt tikai viens Autors
, bet an Autors
var būt daudz grāmatu. The Grāmata
vienība definētu @ManyToOne
attiecības ar Autors
un Autors
vienība definētu @OneToMany
attiecības ar Grāmata
.
@Entity publiskās klases grāmata {@Id private Integer id; privāts virknes nosaukums; @ManyToOne @JoinColumn (name = "AUTHOR_ID") privāts Autors autors; ...}
@Entity public class Autors {@Id @GeneratedValue private Integer id; privāts virknes nosaukums; @OneToMany (mappedBy = "autors") privātu sarakstu grāmatas = jauns ArrayList (); ...}
Šajā gadījumā Autors
klase uztur visu šī autora sarakstīto grāmatu sarakstu un Grāmata
klase saglabā atsauci uz savu vienīgo autoru. Turklāt @JoinColumn
norāda kolonnas nosaukumu Grāmata
tabula, lai saglabātu Autors
.
Daudzas pret daudzām attiecības
Visbeidzot @ManyToMany
anotācija atvieglo saikni starp daudziem pret daudziem. Lūk, gadījums, kad a Grāmata
vienībai ir vairāki Autors
s:
@Entity publiskās klases grāmata {@Id private Integer id; privāts virknes nosaukums; @ManyToMany @JoinTable (name = "BOOK_AUTHORS", joinColumns = @ JoinColumn (name = "BOOK_ID"), inverseJoinColumns = @ JoinColumn (name = "AUTHOR_ID")) privātu kopu autori = new HashSet (); ...}
@Entity public class Autors {@Id @GeneratedValue private Integer id; privāts virknes nosaukums; @ManyToMany (mappedBy = "autors") privātās kopas grāmatas = new HashSet (); ...}
Šajā piemērā mēs izveidojam jaunu tabulu, GRĀMATA_autori
, ar divām kolonnām: BOOK_ID
un AUTHOR_ID
. Izmantojot joinColumns
un inverseJoinColumns
atribūti stāsta jūsu JPA ietvaram, kā kartēt šīs klases attiecībās “daudzi pret daudziem”. The @ManyToMany
anotācija Autors
klase atsaucas uz lauku laukā Grāmata
klase, kas pārvalda attiecības; proti autori
īpašums.
Tas ir ātrs demonstrējums diezgan sarežģītai tēmai. Mēs ienirsim tālāk @JoinTable
un @JoinColumn
anotācijas nākamajā rakstā.
Darbs ar EntityManager
EntityManager
ir klase, kas veic datu bāzes mijiedarbību JPA. Tas tiek inicializēts, izmantojot konfigurācijas failu ar nosaukumu neatlaidība.xml
. Šis fails ir atrodams META-INF
mapē CLASSPATH
, kas parasti tiek iepakots jūsu JAR vai WAR failā. The neatlaidība.xml
failā ir:
- Nosauktā "noturības vienība", kas norāda jūsu izmantoto noturības sistēmu, piemēram, hibernācijas vai EclipseLink.
- Īpašumu kolekcija, kurā norādīts, kā izveidot savienojumu ar datu bāzi, kā arī visi pielāgojumi neatlaidības sistēmā.
- Projekta entītiju klašu saraksts.
Apskatīsim piemēru.
Konfigurēt EntityManager
Pirmkārt, mēs izveidojam EntityManager
izmantojot EntityManagerFactory
iegūts no Neatlaidība
klase:
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory ("Grāmatas"); EntityManager entityManager = entityManagerFactory.createEntityManager ();
Šajā gadījumā mēs esam izveidojuši EntityManager
kas ir savienots ar "Books" noturības vienību, kuru esam konfigurējuši neatlaidība.xml
failu.
The EntityManager
klase nosaka, kā mūsu programmatūra mijiedarbosies ar datu bāzi, izmantojot JPA entītijas. Šeit ir dažas no izmantotajām metodēm EntityManager
:
atrast
izgūst entītiju ar tās galveno atslēgu.createQuery
izveido aVaicājums
gadījumu, kuru var izmantot, lai izgūtu entītijas no datu bāzes.createNamedQuery
slodzes aVaicājums
kas ir definēts a@ NosauktsQuery
anotācija vienā no noturības entītijām. Nosauktie vaicājumi nodrošināt tīru mehānismu JPA vaicājumu centralizēšanai noturības klases definīcijā, kurā vaicājums tiks izpildīts.getTransaction
definēEntityTransaction
izmantot datu bāzes mijiedarbībā. Tāpat kā datubāzes darījumi, parasti jūs sāksit darījumu, veiksit savas darbības un pēc tam darīsit vai atcelsiet darījumu. ThegetTransaction ()
metode ļauj piekļūt šai uzvedībaiEntityManager
, nevis datu bāzi.apvienot ()
Pievieno entītiju noturības kontekstam, lai, veicot darījumu, entītija tiktu saglabāta datu bāzē. Lietojotapvienot ()
, objekti netiek pārvaldīti.saglabājas
Pievieno entītiju noturības kontekstam, lai, veicot darījumu, entītija tiktu saglabāta datu bāzē. Lietojotpastāvēt ()
, objekti tiek pārvaldīti.atjaunot
atsvaidzina pašreizējās entītijas stāvokli no datu bāzes.noskalot
sinhronizē noturības konteksta stāvokli ar datu bāzi.
Neuztraucieties par visu šo metožu integrēšanu vienlaikus. Jūs tos iepazīsit, tieši sadarbojoties ar EntityManager
, ko mēs darīsim vairāk nākamajā sadaļā.