Ohjelmointi

Java-pysyvyys JPA: n ja horrostilan kanssa, osa 1: Entiteetit ja suhteet

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 kokonaislukutai 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äprofiilion 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 Kirjoittajas:

 @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 luo Kysely ilmentymä, jota voidaan käyttää entiteettien hakemiseen tietokannasta.
  • createNamedQuery kuormat a Kysely 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äärittelee EntityTransaction 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.

$config[zx-auto] not found$config[zx-overlay] not found