„Java Persistence API“ (JPA) yra „Java“ specifikacija, kuri užpildo atotrūkį tarp reliacinių duomenų bazių ir objektinio programavimo. Šioje dviejų dalių pamokoje pristatoma JPA ir paaiškinama, kaip „Java“ objektai modeliuojami kaip JPA subjektai, kaip apibrėžiami subjektų santykiai ir kaip naudoti JPA „EntityManager“
su „Java“ programų saugyklos modeliu.
Atkreipkite dėmesį, kad šioje pamokoje naudojamas užmigdymo režimas kaip JPA teikėjas. Daugumą sąvokų galima išplėsti ir kitose „Java“ patvarumo sistemose.
Kas yra JPA?
Norėdami sužinoti apie JPA evoliuciją ir susijusias sistemas, įskaitant EJB 3.0, skaitykite „Kas yra JPA? Įvadas į„ Java Persistence API “. ir JDBC.
Objektiniai santykiai JPA
Reliacinės duomenų bazės kaip priemonė saugoti programos duomenis egzistavo nuo 1970-ųjų. Nors šiandien kūrėjai turi daug alternatyvų reliacinei duomenų bazei, tokio tipo duomenų bazė yra keičiamo dydžio ir gerai suprantama, ir vis dar plačiai naudojama kuriant mažos ir didelės apimties programinę įrangą.
„Java“ objektai reliacinės duomenų bazės kontekste apibrėžiami kaip subjektai. Subjektai dedami į lenteles, kur jie užima stulpelius ir eilutes. Programuotojai naudoja svetimi raktai ir sujungti stalus apibrėžti santykius tarp subjektų - būtent vienas nuo vieno, vienas prie daugelio ir daug iš daugelio. Taip pat galime naudoti SQL („Structured Query Language“), norėdami gauti ir sąveikauti su duomenimis atskirose lentelėse ir keliose lentelėse, naudodami užsienio raktų apribojimus. Reliacinis modelis yra plokščias, tačiau kūrėjai gali rašyti užklausas, kad gautų duomenis ir konstruotų objektus iš tų duomenų.
Objekto ir santykio impedanso neatitikimas
Jums gali būti žinomas šis terminas objekto ir santykio impedanso neatitikimas, kuris nurodo iššūkį susieti duomenų objektus su reliacine duomenų baze. Šis neatitikimas įvyksta todėl, kad į objektą orientuotas dizainas neapsiriboja santykiais „vienas su vienu“, „vienas su daugeliu“ ir „daug prieš daugelį“. Vietoj to, projektuodami objektą, mes galvojame apie objektus, jų atributus ir elgseną bei tai, kaip objektai yra susiję. Du pavyzdžiai yra kapsuliavimas ir paveldėjimas:
- Jei objekte yra kitas objektas, mes tai apibrėžiame kapsuliavimas--a turi santykiai.
- Jei objektas yra kito objekto specializacija, mes tai apibrėžiame per paveldėjimas- yra santykiai.
Asociacija, agregavimas, kompozicija, abstrakcija, apibendrinimas, realizavimas ir priklausomybės yra visos į objektą orientuotos programavimo koncepcijos, kurias gali būti sunku susieti su reliaciniu modeliu.
ORM: Objekto ir reliacijos atvaizdavimas
Neatitikimas tarp objektinio dizaino ir reliacinių duomenų bazių modeliavimo leido sukurti įrankių klasę, sukurtą specialiai objekto-reliaciniam atvaizdavimui (ORM). Tokie ORM įrankiai kaip „Hibernate“, „EclipseLink“ ir „iBatis“ paverčia reliacinių duomenų bazių modelius, įskaitant objektus ir jų ryšius, į objektinius modelius. Daugelis šių įrankių egzistavo dar prieš JPA specifikaciją, tačiau be standarto jų funkcijos priklausė nuo pardavėjo.
Pirmą kartą išleista kaip „EJB 3.0“ dalis 2006 m., „Java Persistence API“ (JPA) siūlo standartinį būdą komentuoti objektus, kad juos būtų galima susieti ir išsaugoti reliacinėje duomenų bazėje. Specifikacija taip pat apibrėžia bendrą sąveikos su duomenų bazėmis konstrukciją. ORM standarto naudojimas „Java“ suteikia nuoseklumo tiekėjų diegimui, kartu suteikdamas lankstumo ir priedų. Pavyzdžiui, nors pirminė JPA specifikacija yra taikoma reliacinėms duomenų bazėms, kai kurie tiekėjų diegimai išplėtė JPA naudojimui su NoSQL duomenų bazėmis.
JPA raida
Pirmasis JPA leidimas, 1.0 versija, buvo paskelbtas 2006 m. Naudojant „Java Community Process“ (JCP) kaip „Java Specification Request“ (JSR) 220. Versija 2.0 (JSR 317) buvo paskelbta 2009 m., 2.1 versija (JSR 338) 2013 m. ir 2.2 versija („JSR 338“ techninės priežiūros leidimas) buvo paskelbta 2017 m. JPA 2.2 buvo pasirinkta įtraukti ir nuolat tobulinti Džakarta EE.
Darbo su JPA pradžia
„Java Persistence“ API yra specifikacija, o ne įgyvendinimas: ji apibrėžia bendrą abstrakciją, kurią galite naudoti savo kode sąveikaudami su ORM produktais. Šiame skyriuje apžvelgiamos kai kurios svarbios JPA specifikacijos dalys.
Sužinosite, kaip:
- Duomenų bazėje apibrėžkite objektus, laukus ir pagrindinius raktus.
- Kurkite ryšius tarp duomenų bazėje esančių subjektų.
- Darbas su
„EntityManager“
ir jos metodai.
Apibrėžiantys subjektai
Norėdami apibrėžti objektą, turite sukurti klasę, kuri yra pažymėta @Entity
anotacija. @Entity
anotacija yra a žymeklio anotacija, kuris naudojamas patvariems subjektams atrasti. Pvz., Jei norite sukurti knygos esmę, ją komentuokite taip:
„@Entity“ viešosios klasės knyga {...}
Pagal numatytuosius nustatymus šis objektas bus susietas su Knyga
lentelę, nustatytą pagal nurodytą klasės pavadinimą. Jei norėtumėte susieti šį objektą su kita lentele (ir pasirinktinai konkrečia schema), galite naudoti @ Lentelė
anotacija tai padaryti. Štai kaip jūs žemėlapį sudarytumėte Knyga
klasė prie KNYGŲ lentelės:
@Entity @Table (name = "BOOKS") viešosios klasės knyga {...}
Jei lentelė KNYGOS buvo schemoje PUBLISHING, schemą galite pridėti prie @ Lentelė
anotacija:
@Table (pavadinimas = "KNYGOS", schema = "PUBLISHING")
Laukų susiejimas su stulpeliais
Kai objektas susietas su lentele, kita jūsų užduotis yra apibrėžti jos laukus. Laukai yra apibrėžti kaip narių kintamieji klasėje, kiekvieno lauko pavadinimas susietas su stulpelio pavadinimu lentelėje. Galite nepaisyti šio numatytojo susiejimo naudodami @Kolonas
anotacija, kaip parodyta čia:
@Entity @Table (name = "BOOKS") public class Book {private String name; @Column (name = "ISBN_NUMBER") privati eilutė isbn; ...}
Šiame pavyzdyje priėmėme numatytąjį „“ susiejimą vardas
atributas, bet nurodė pasirinktinį isbn
atributas. vardas
atributas bus susietas su vardas stulpelį, bet isbn
atributas bus susietas su stulpeliu ISBN_NUMBER.
@Kolonas
anotacija leidžia mums apibrėžti papildomas lauko / stulpelio savybes, įskaitant ilgį, ar jis yra niekinis, ar jis turi būti unikalus, ar jo tikslumas ir mastelis (jei tai yra dešimtainė reikšmė), ar jis yra įterpiamas ir atnaujinamas, ir pan.
Nurodomas pagrindinis raktas
Vienas iš reliacinės duomenų bazės lentelės reikalavimų yra tas, kad joje turi būti pagrindinis raktas, arba raktas, unikaliai identifikuojantis konkrečią duomenų bazės eilutę. JPA mes naudojame @Id
anotacija, kad laukas būtų pagrindinis lentelės raktas. Pirminis raktas turi būti „Java“ primityvus tipas, primityvus paketas, pvz Sveikasis skaičius
arba Ilgas
, a Stygos
, a Data
, a BigInteger
arba a Didelis dešimtainis
.
Šiame pavyzdyje mes žemėlapį id
atributas, kuris yra Sveikasis skaičius
, į lentelės KNYGOS stulpelį ID:
@Entity @Table (name = "BOOKS") viešosios klasės knygos {@Id private Integer id; asmeninės eilutės pavadinimas; @Column (name = "ISBN_NUMBER") privati eilutė isbn; ...}
Taip pat galima sujungti @Id
anotacija su @Kolonas
anotacija, skirta perrašyti pirminio rakto stulpelių ir pavadinimų atvaizdavimą.
Santykiai tarp subjektų
Dabar, kai žinote, kaip apibrėžti esmę, pažiūrėkime, kaip sukurti santykius tarp subjektų. JPA apibrėžia keturias subjektų apibrėžimo anotacijas:
@OneToOne
@OneToMany
@ManyToOne
@ManyToMany
Santykiai „vienas su vienu“
@OneToOne
anotacija naudojama apibrėžiant dviejų subjektų tarpusavio santykius. Pavyzdžiui, galite turėti Vartotojas
subjektas, kuriame yra vartotojo vardas, el. pašto adresas ir slaptažodis, tačiau galbūt norėsite atskiroje atskiroje vietoje išsaugoti papildomą informaciją apie vartotoją (pvz., amžių, lytį ir mėgstamą spalvą). Vartotojo profilis
subjektas. @OneToOne
anotacija palengvina jūsų duomenų ir subjektų suskaidymą tokiu būdu.
Vartotojas
žemiau esanti klasė turi vienintelį Vartotojo profilis
instancija. Vartotojo profilis
žemėlapiai į vieną Vartotojas
instancija.
@Entity viešosios klasės naudotojo {@Id privataus sveiko skaičiaus ID; asmeninis eilutės el. paštas; asmeninės eilutės pavadinimas; asmeninės eilutės slaptažodis; @OneToOne (mappedBy = "user") privatus „UserProfile“ profilis; ...}
@Entity viešosios klasės „UserProfile“ {@Id private Integer ID; privatus int amžius; privati Styginių lytis; privati styginių mėgstamiausia spalva; @OneToOne privatus Vartotojo vartotojas; ...}
JPA teikėjas naudoja Vartotojo profilis
's Vartotojas
laukas žemėlapiui Vartotojo profilis
į Vartotojas
. Žemėlapis nurodytas atvaizduota
atributas @OneToOne
anotacija.
Santykiai „vienas su daugeliu“ ir „vienas su kitu“
@OneToMany
ir @ManyToOne
anotacijos palengvina abi to paties santykio puses. Apsvarstykite pavyzdį, kai a Knyga
gali turėti tik vieną Autorius
, bet an Autorius
gali turėti daug knygų. Knyga
subjektas apibrėžtų a @ManyToOne
santykiai su Autorius
ir Autorius
subjektas apibrėžtų a @OneToMany
santykiai su Knyga
.
@Entity viešosios klasės knyga {@Id private Integer id; asmeninės eilutės pavadinimas; @ManyToOne @JoinColumn (vardas = "AUTHOR_ID") privatus Autorius autorius; ...}
@Entity public class Autorius {@Id @GeneratedValue private Integer ID; asmeninės eilutės pavadinimas; @OneToMany (mappedBy = "author") private list books = new ArrayList (); ...}
Šiuo atveju Autorius
klasė tvarko visų to autoriaus parašytų knygų sąrašą Knyga
klasė palaiko nuorodą į savo vienintelį autorių. Be to, @JoinColumn
nurodo stulpelio pavadinimą Knyga
lentelę, kurioje saugomas Autorius
.
Santykiai nuo daugelio iki daugelio
Galiausiai @ManyToMany
anotacija palengvina daugelio daugeliui santykius. Štai atvejis, kai a Knyga
subjektas turi kelis Autorius
s:
@Entity viešosios klasės knyga {@Id private Integer id; asmeninės eilutės pavadinimas; @ManyToMany @JoinTable (name = "BOOK_AUTHORS", joinColumns = @ JoinColumn (name = "BOOK_ID"), inverseJoinColumns = @ JoinColumn (name = "AUTHOR_ID")) private Set author = new HashSet (); ...}
@Entity public class Autorius {@Id @GeneratedValue private Integer ID; asmeninės eilutės pavadinimas; @ManyToMany (mappedBy = "author") private Set books = new HashSet (); ...}
Šiame pavyzdyje sukuriame naują lentelę, BOOK_AUTHORS
, su dviem stulpeliais: BOOK_ID
ir AUTHOR_ID
. Naudojant joinColumns
ir inverseJoinColumns
atributai jūsų JPA sistemai nurodo, kaip susieti šias klases santykiuose „visi daugeliui“. @ManyToMany
anotacija Autorius
klasė nurodo lauką Knyga
klasė, kuri valdo santykius; būtent autoriai
nuosavybė.
Tai greita gana sudėtingos temos demonstracija. Nersime toliau į @JoinTable
ir @JoinColumn
anotacijos kitame straipsnyje.
Darbas su „EntityManager“
„EntityManager“
yra klasė, atliekanti duomenų bazių sąveiką JPA. Jis inicijuojamas per konfigūracijos failą, pavadintą atkaklumas.xml
. Šis failas yra META-INF
aplanką CLASSPATH
, kuris paprastai yra supakuotas į JAR arba WAR failą. atkaklumas.xml
faile yra:
- Pavadintas „patvarumo vienetas“, nurodantis jūsų naudojamą patvarumo struktūrą, pvz., „Hibernate“ arba „EclipseLink“.
- Ypatybių rinkinys, nurodantis, kaip prisijungti prie duomenų bazės, taip pat visi tinkamumo patvarumo sistemoje.
- Jūsų projekto objektų klasių sąrašas.
Pažvelkime į pavyzdį.
„EntityManager“ konfigūravimas
Pirma, mes sukuriame „EntityManager“
naudojant „EntityManagerFactory“
gauta iš Atkaklumas
klasė:
EntityManagerFactory EntityManagerFactory = Persistence.createEntityManagerFactory („Knygos“); EntityManager entityManager = entityManagerFactory.createEntityManager ();
Šiuo atveju mes sukūrėme „EntityManager“
, kuris yra prijungtas prie „Knygų“ patvarumo bloko, kurį sukonfigūravome atkaklumas.xml
failą.
„EntityManager“
klasė apibrėžia, kaip mūsų programinė įranga sąveikaus su duomenų baze per JPA subjektus. Štai keletas metodų, kuriuos naudoja „EntityManager“
:
rasti
nuskaito subjektą pagrindiniu raktu.createQuery
sukuria aUžklausa
egzempliorius, kurį galima naudoti norint gauti objektus iš duomenų bazės.createNamedQuery
apkrovos aUžklausa
kad buvo apibrėžta a@PavadintaKlausimas
anotacija vieno iš patvarumo subjektų viduje. Pavadintos užklausos pateikite aiškų JPA užklausų centralizavimo mechanizmą apibrėžiant patvarumo klasę, pagal kurią bus vykdoma užklausa.„getTransaction“
apibrėžia„EntityTransaction“
naudoti jūsų duomenų bazės sąveikose. Kaip ir duomenų bazės operacijos, paprastai pradėsite operaciją, atliksite operacijas ir tada atliksite arba grąžinsite operaciją.„getTransaction“ ()
metodas leidžia jums pasiekti šią elgseną„EntityManager“
, o ne duomenų bazę.sujungti ()
prideda subjektą prie patvarumo konteksto, kad įvykdžius operaciją, subjektas išliktų duomenų bazėje. Naudojantsujungti ()
, objektai nėra valdomi.išlieka
prideda subjektą prie patvarumo konteksto, kad įvykdžius operaciją, subjektas išliktų duomenų bazėje. Naudojantišlikti ()
, objektai yra valdomi.atnaujinti
atnaujina dabartinio objekto būseną iš duomenų bazės.praplaukite
sinchronizuoja patvarumo konteksto būseną su duomenų baze.
Nesijaudinkite dėl visų šių metodų integravimo vienu metu. Su jais susipažinsite tiesiogiai dirbdami su „EntityManager“
, kurį atliksime daugiau kitame skyriuje.