Java Persistence API (JPA) on Java-määritys, joka yhdistää relaatiotietokantojen ja olio-ohjelmoinnin välisen kuilun. Tämä kaksiosainen opetusohjelma esittelee JPA: n ja selittää kuinka Java-objektit mallinnetaan JPA-entiteeteiksi, miten entiteettisuhteet määritetään ja miten JPA: ta käytetään EntityManager
Java-sovellusten Repository-mallin kanssa.
Huomaa, että tässä opetusohjelmassa käytetään horrostilaa JPA-tarjoajana. Suurin osa käsitteistä voidaan laajentaa muihin Java-pysyvyyskehyksiin.
Mikä on JPA?
Lisätietoja JPA: n ja siihen liittyvien kehysten, mukaan lukien EJB 3.0, kehityksestä on kohdassa "Mikä on JPA? Johdatus Java Persistence -sovellusliittymään". ja JDBC.
Objektisuhteet JPA: ssa
Relaatiotietokannat ovat olleet keinona ohjelmatietojen tallentamiseen 1970-luvulta lähtien. Vaikka kehittäjillä on nykyään monia vaihtoehtoja relaatiotietokannalle, tämän tyyppinen tietokanta on skaalautuva ja hyvin ymmärrettävä, ja sitä käytetään edelleen laajalti pienten ja suurten ohjelmistojen kehittämisessä.
Java-objektit relaatiotietokantakontekstissa määritellään seuraavasti yhteisöt. Entiteetit sijoitetaan taulukoihin, joissa ne vievät sarakkeita ja rivejä. Ohjelmoijat käyttävät vieraat avaimet ja liittyä pöytiin määritellä yksiköiden väliset suhteet - nimittäin yksi yhteen, yksi moniin ja monet moniin -suhteet. Voimme myös käyttää SQL: ää (strukturoitu kyselykieli) hakemaan tietoja ja olemaan vuorovaikutuksessa yksittäisten taulukkojen ja useiden taulukoiden tietojen kanssa käyttämällä ulkomaisia avainrajoituksia. Relaatiomalli on tasainen, mutta kehittäjät voivat kirjoittaa kyselyjä tietojen noutamiseksi ja objektien rakentamiseksi näistä tiedoista.
Kohde-suhteiden impedanssin epäsuhta
Saatat olla perehtynyt termiin objekti-suhteiden impedanssin epäsuhta, joka viittaa haasteeseen kartoittaa dataobjekteja relaatiotietokantaan. Tämä ristiriita johtuu siitä, että objektisuuntautunut suunnittelu ei rajoitu suhteisiin "yksi yhteen", "yksi moniin" ja "monet moniin". Sen sijaan ajattelemme objektisuuntautuneessa suunnittelussa esineitä, niiden ominaisuuksia ja käyttäytymistä sekä kuinka objektit liittyvät toisiinsa. Kaksi esimerkkiä ovat kapselointi ja perintö:
- Jos objekti sisältää toisen objektin, määritämme sen kautta kapselointi--a on-a suhde.
- Jos objekti on erikoistunut toiseen objektiin, määritämme sen kautta perintö--an on suhde.
Assosiaatio, yhdistäminen, sommittelu, abstraktio, yleistys, toteutus ja riippuvuudet ovat kaikki olio-ohjelmointikonsepteja, jotka voivat olla haastavia kartoittaa relaatiomalliin.
ORM: Objektisuhdekartoitus
Kohdistetun suunnittelun ja relaatiotietokantamallinnuksen välinen ristiriita on johtanut työkaluluokkaan, joka on kehitetty erityisesti objektisuhdekartoitusta (ORM) varten. ORM-työkalut, kuten Hibernate, EclipseLink ja iBatis, muuntavat relaatiotietokantamallit, mukaan lukien entiteetit ja niiden suhteet, olio-malleiksi. Monet näistä työkaluista olivat olemassa ennen JPA-määrittelyä, mutta ilman standardia niiden ominaisuudet riippuivat toimittajista.
Java Persistence API (JPA), joka julkaistiin ensimmäisen kerran osana EJB 3.0: ta vuonna 2006, tarjoaa tavanomaisen tavan merkitä objekteja, jotta ne voidaan kartoittaa ja tallentaa relaatiotietokantaan. Määrittely määrittelee myös yhteisen rakenteen vuorovaikutukseen tietokantojen kanssa. ORM-standardin käyttö Java-käyttöjärjestelmälle tuo johdonmukaisuuden toimittajien toteutuksiin samalla, kun se mahdollistaa joustavuuden ja lisäosat. Esimerkiksi, vaikka alkuperäinen JPA-määritys on sovellettavissa relaatiotietokantoihin, jotkut toimittajien toteutukset ovat laajentaneet JPA: ta käytettäväksi NoSQL-tietokantojen kanssa.
JPA: n kehitys
JPA: n ensimmäinen versio, versio 1.0, julkaistiin vuonna 2006 Java-yhteisöprosessin (JCP) kautta nimellä Java Specification Request (JSR) 220. Versio 2.0 (JSR 317) julkaistiin vuonna 2009, versio 2.1 (JSR 338) vuonna 2013, ja versio 2.2 (JSR 338: n ylläpitoversio) julkaistiin vuonna 2017. JPA 2.2 on valittu sisällytettäväksi ja jatkuvaan kehittämiseen Jakarta EE: ssä.
JPA: n käytön aloittaminen
Java Persistence -sovellusliittymä on määrittely, ei toteutus: se määrittelee yleisen abstraktion, jota voit käyttää koodissasi vuorovaikutuksessa ORM-tuotteiden kanssa. Tässä osassa tarkastellaan JPA-spesifikaation tärkeitä osia.
Opit kuinka:
- Määritä tietokannan entiteetit, kentät ja ensisijaiset avaimet.
- Luo suhteita tietokannan entiteettien välille.
- Työskentele
EntityManager
ja sen menetelmät.
Määritellään entiteetit
Entiteetin määrittelemiseksi sinun on luotava luokka, johon on merkitty @Entity
merkintä. @Entity
merkintä on a merkinnän merkintä, jota käytetään pysyvien entiteettien löytämiseen. Jos esimerkiksi haluat luoda kirja-entiteetin, merkitkää se seuraavasti:
@Entity julkisen luokan kirja {...}
Oletusarvon mukaan tämä entiteetti kartoitetaan Kirja
taulukon mukaan määritetyn luokan nimen mukaan. Jos haluat kartoittaa tämän entiteetin toiseen taulukkoon (ja mahdollisesti tiettyyn skeemaan), voit käyttää sitä @Pöytä
huomautus tehdä niin. Näin kartoitat Kirja
luokka VARAT-taulukkoon:
@Entity @Table (name = "BOOKS") julkisen luokan kirja {...}
Jos BOOKS-taulukko oli JULKAISEMA-skeemassa, voit lisätä mallin @Pöytä
merkintä:
@Table (name = "BOOKS", schema = "PUBLISHING")
Kenttien yhdistäminen sarakkeisiin
Kun entiteetti on yhdistetty taulukkoon, seuraava tehtävä on määrittää sen kentät. Kentät määritellään luokan jäsenmuuttujiksi, ja kunkin kentän nimi on yhdistetty taulukon sarakkeen nimeen. Voit ohittaa tämän oletuskartoituksen käyttämällä @Column
merkintä, kuten tässä on esitetty:
@Entity @Table (name = "BOOKS") public class Book {yksityisen merkkijonon nimi; @Column (name = "ISBN_NUMBER") yksityinen merkkijono isbn; ...}
Tässä esimerkissä olemme hyväksyneet oletuskartoituksen nimi
attribuutti, mutta määritti mukautetun kartoituksen isbn
määritteen. nimi
attribuutti kartoitetaan nimi -saraketta, mutta isbn
attribuutti kartoitetaan ISBN_NUMBER -sarakkeeseen.
@Column
merkinnän avulla voimme määritellä kentän / sarakkeen lisäominaisuudet, mukaan lukien pituus, onko se mitätöitävissä, onko sen oltava ainutlaatuinen, tarkkuuden ja mittakaavan (jos se on desimaaliarvo), onko se lisättävä ja päivitettävä, ja niin edelleen.
Ensisijaisen avaimen määrittäminen
Yksi relaatiotietokantataulukon vaatimuksista on, että sen on sisällettävä a pääavaintai avain, joka yksilöi tietyn tietyn tietokannan rivin. JPA: ssa käytämme @Id
merkintä kentän nimeämiseksi taulukon ensisijaiseksi avaimeksi. Ensisijaisen avaimen on oltava Java-primitiivinen tyyppi, primitiivinen kääre, kuten Kokonaisluku
tai Pitkä
, a Merkkijono
, a Päivämäärä
, a Iso kokonaisluku
tai a BigDecimal
.
Tässä esimerkissä kartoitamme id
attribuutti, joka on Kokonaisluku
, VARAT-taulukon ID-sarakkeeseen:
@Entity @Table (name = "BOOKS") julkisen luokan kirja {@Id private Integer id; yksityinen merkkijono nimi; @Column (name = "ISBN_NUMBER") yksityinen merkkijono isbn; ...}
On myös mahdollista yhdistää @Id
merkintä @Column
huomautus pääavaimen sarake-nimen kartoituksen korvaamiseksi.
Yksiköiden väliset suhteet
Nyt kun tiedät kuinka määritellä entiteetti, katsotaan miten luoda suhteita entiteettien välille. JPA määrittelee neljä merkintää entiteettien määrittelemiselle:
@Yksi yhteen
@OneToMany
@ManyToOne
@ManyToMany
Henkilökohtaiset suhteet
@Yksi yhteen
merkintää käytetään määrittelemään kahden kohteen välinen henkilökohtainen suhde. Sinulla voi olla esimerkiksi Käyttäjä
entiteetti, joka sisältää käyttäjän nimen, sähköpostiosoitteen ja salasanan, mutta saatat haluta säilyttää lisätietoja käyttäjästä (kuten ikä, sukupuoli ja suosikkiväri) erillisenä Käyttäjäprofiili
kokonaisuus. @Yksi yhteen
merkintä helpottaa tietojen ja entiteettien hajottamista tällä tavalla.
Käyttäjä
alla olevalla luokassa on yksi Käyttäjäprofiili
ilmentymä. Käyttäjäprofiili
kartat yhdeksi Käyttäjä
ilmentymä.
@Entity public class User {@Id private Integer id; yksityinen merkkijono sähköposti; yksityinen merkkijono nimi; yksityinen merkkijono salasana; @OneToOne (mappedBy = "käyttäjä") yksityinen UserProfile-profiili; ...}
@Entity public class UserProfile {@Id private Integer id; yksityinen ikä; yksityinen String sukupuoli; yksityinen merkkijono suosikkiVäri; @OneToOne yksityisen käyttäjän käyttäjä; ...}
JPA-palveluntarjoaja käyttää Käyttäjäprofiili
on käyttäjä
kenttä kartoitettavaksi Käyttäjäprofiili
että Käyttäjä
. Kartoitus on määritelty kartoitettu
attribuutti @Yksi yhteen
merkintä.
Ihmissuhteet moniin ja moniin yhteen
@OneToMany
ja @ManyToOne
merkinnät helpottavat saman suhteen molempia puolia. Tarkastellaan esimerkkiä, jossa a Kirja
voi olla vain yksi Kirjoittaja
, mutta Kirjoittaja
voi olla monia kirjoja. Kirja
yksikkö määrittäisi a @ManyToOne
suhde Kirjoittaja
ja Kirjoittaja
yksikkö määrittäisi a @OneToMany
suhde Kirja
.
@Entity public class Book {@Id private Integer id; yksityinen merkkijono nimi; @ManyToOne @JoinColumn (name = "AUTHOR_ID") yksityinen kirjailija; ...}
@Entity public class Author {@Id @GeneratedValue private Integer id; yksityinen merkkijono nimi; @OneToMany (mappedBy = "kirjailija") yksityinen luettelokirja = new ArrayList (); ...}
Tässä tapauksessa Kirjoittaja
luokka ylläpitää luetteloa kaikista kyseisen kirjoittajan ja Kirja
luokka ylläpitää viittausta ainoaan kirjoittajaansa. Lisäksi @JoinColumn
määrittää sarakkeen nimen Kirja
taulukko tallentaa tunnuksen Kirjoittaja
.
Monista moniin-suhteet
Lopuksi @ManyToMany
merkinnät helpottavat monien monien suhdetta entiteettien välillä. Tässä on tapaus, jossa a Kirja
yhteisöllä on useita Kirjoittaja
s:
@Entity public class Book {@Id private Integer id; yksityinen merkkijono nimi; @ManyToMany @JoinTable (name = "BOOK_AUTHORS", joinColumns = @ JoinColumn (name = "BOOK_ID"), inverseJoinColumns = @ JoinColumn (name = "AUTHOR_ID")) private Set tekijät = uusi HashSet (); ...}
@Entity public class Author {@Id @GeneratedValue private Integer id; yksityinen merkkijono nimi; @ManyToMany (mappedBy = "tekijä") yksityisjoukon kirjat = new HashSet (); ...}
Tässä esimerkissä luomme uuden taulukon, BOOK_AUTHORS
, kahdella sarakkeella: BOOK_ID
ja AUTHOR_ID
. Käyttämällä joinColumns
ja inverseJoinColumns
attributes kertoo JPA-kehyksellesi, kuinka nämä luokat kartoitetaan monien ja monien välillä. @ManyToMany
merkintä Kirjoittaja
luokka viittaa kenttään Kirja
luokka, joka hoitaa suhdetta; nimittäin kirjoittajat
omaisuus.
Se on nopea demo melko monimutkaisesta aiheesta. Sukellamme syvemmälle @JoinTable
ja @JoinColumn
merkinnät seuraavassa artikkelissa.
Työskentely EntityManagerin kanssa
EntityManager
on luokka, joka suorittaa tietokannan vuorovaikutusta JPA: ssa. Se alustetaan määritystiedostolla nimeltä pysyvyys.xml
. Tämä tiedosto löytyy META-INF
kansiossa CLASSPATH
, joka on yleensä pakattu JAR- tai WAR-tiedostoon. pysyvyys.xml
tiedosto sisältää:
- Nimetty "pysyvyysyksikkö", joka määrittää käyttämäsi pysyvyyskehyksen, kuten horrostila tai EclipseLink.
- Kokoelma ominaisuuksia, jotka määrittelevät yhteyden muodostamisen tietokantaan, sekä mahdolliset mukautukset pysyvyyskehyksessä.
- Luettelo projektisi kokonaisuusluokista.
Katsotaanpa esimerkkiä.
EntityManagerin määrittäminen
Ensinnäkin luomme EntityManager
käyttämällä EntityManagerFactory
haettu Sitkeys
luokka:
EntityManagerFactory EntityManagerFactory = Persistence.createEntityManagerFactory ("Kirjat"); EntityManager entitManager = entitManagerFactory.createEntityManager ();
Tässä tapauksessa olemme luoneet EntityManager
joka on kytketty Kirjat - pysyvyysyksikköön, jonka olemme määrittäneet pysyvyys.xml
tiedosto.
EntityManager
luokka määrittää, miten ohjelmistomme on vuorovaikutuksessa tietokannan kanssa JPA-entiteettien kautta. Tässä on joitain menetelmiä, joita EntityManager
:
löytö
hakee entiteetin ensisijaisella avaimellaan.createQuery
luoKysely
ilmentymä, jota voidaan käyttää entiteettien hakemiseen tietokannasta.createNamedQuery
kuormat aKysely
joka on määritelty kohdassa a@NimedQuery
merkintä yhden pysyvyys-entiteetin sisällä. Nimetyt kyselyt tarjota puhdas mekanismi JPA-kyselyjen keskittämiseksi pysyvyysluokan määrittelyyn, jolle kysely suoritetaan.getTransaction
määritteleeEntityTransaction
käyttää tietokannan vuorovaikutuksessa. Aivan kuten tietokantatapahtumat, aloitat tyypillisesti tapahtuman, suoritat toiminnot ja sitten joko sitoutat tai palautat tapahtuman.getTransaction ()
-menetelmän avulla voit käyttää tätä käyttäytymistäEntityManager
, eikä tietokantaan.yhdistää()
lisää entiteetin pysyvyyskontekstiin, joten kun tapahtuma on tehty, entiteetti pysyy tietokannassa. Käytettäessäyhdistää()
, objekteja ei hallita.jatkuvat
lisää entiteetin pysyvyyskontekstiin, joten kun tapahtuma on tehty, entiteetti pysyy tietokannassa. Käytettäessäjatkua ()
, objekteja hallitaan.virkistää
päivittää nykyisen entiteetin tilan tietokannasta.huuhtele
synkronoi pysyvyyskontekstin tilan tietokantaan.
Älä huoli kaikkien näiden menetelmien integroinnista kerralla. Opit tuntemaan heidät työskentelemällä suoraan EntityManager
, jonka teemme enemmän seuraavassa osassa.