Programmēšana

Java neatlaidība ar JPA un hibernātu, 1. daļa: Entītijas un attiecības

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 BigIntegervai 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 Autorss:

 @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 a Vaicājums gadījumu, kuru var izmantot, lai izgūtu entītijas no datu bāzes.
  • createNamedQuery slodzes a Vaicā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. The getTransaction () metode ļauj piekļūt šai uzvedībai EntityManager, nevis datu bāzi.
  • apvienot () Pievieno entītiju noturības kontekstam, lai, veicot darījumu, entītija tiktu saglabāta datu bāzē. Lietojot apvienot (), 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ē. Lietojot pastā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ļā.

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