JavaRush /Java Blog /Random-TL /JPA: Ipinapakilala ang Teknolohiya

JPA: Ipinapakilala ang Teknolohiya

Nai-publish sa grupo
Ang modernong mundo ng pag-unlad ay puno ng iba't ibang mga pagtutukoy na idinisenyo upang gawing mas madali ang buhay. Alam ang mga tool, maaari mong piliin ang tama. Nang hindi mo nalalaman, maaari mong gawing mas mahirap ang iyong buhay. Itataas ng pagsusuring ito ang belo ng lihim sa konsepto ng JPA - Java Persistence API. Umaasa ako na pagkatapos ng pagbabasa ay naisin mong sumisid ng mas malalim sa mahiwagang mundong ito.
JPA : Panimula sa Teknolohiya - 1

Panimula

Tulad ng alam natin, ang isa sa mga pangunahing gawain ng mga programa ay ang pag-iimbak at pagproseso ng data. Noong unang panahon, ang mga tao ay nag-imbak lamang ng data sa mga file. Ngunit sa sandaling kailangan ang sabay-sabay na pag-access sa pagbabasa at pag-edit, kapag may pag-load (ibig sabihin, maraming mga kahilingan ang dumating sa parehong oras), ang pag-iimbak ng data lamang sa mga file ay nagiging isang problema. Para sa higit pang impormasyon tungkol sa kung anong mga problema ang nalulutas ng mga database at kung paano, ipinapayo ko sa iyo na basahin ang artikulong " Paano nakabalangkas ang mga database ." Nangangahulugan ito na nagpasya kaming iimbak ang aming data sa isang database. Sa loob ng mahabang panahon, ang Java ay nakapagtrabaho sa mga database gamit ang JDBC API (The Java Database Connectivity). Maaari kang magbasa ng higit pa tungkol sa JDBC dito: “ JDBC o kung saan nagsisimula ang lahat .” Ngunit lumipas ang oras at ang mga developer sa bawat oras ay nahaharap sa pangangailangan na magsulat ng parehong uri at hindi kinakailangang "pagpapanatili" na code (ang tinatawag na Boilerplate code) para sa mga walang kuwentang operasyon ng pag-save ng mga bagay ng Java sa database at kabaliktaran, na lumilikha ng mga Java object gamit ang data mula sa database. At pagkatapos, upang malutas ang mga problemang ito, ipinanganak ang isang konsepto tulad ng ORM. ORM - Object-Relational Mapping o isinalin sa Russian object-relational mapping. Ito ay isang programming technology na nag-uugnay sa mga database sa mga konsepto ng object-oriented programming language. Upang pasimplehin, ang ORM ay ang koneksyon sa pagitan ng mga Java object at mga tala sa isang database: JPA: Panimula sa Teknolohiya - 2Ang ORM ay mahalagang konsepto na ang isang Java object ay maaaring katawanin bilang data sa isang database (at vice versa). Ito ay nakapaloob sa anyo ng detalye ng JPA - Java Persistence API. Ang detalye ay isa nang paglalarawan ng Java API na nagpapahayag ng konseptong ito. Sinasabi sa amin ng detalye kung anong mga tool ang dapat naming ibigay (ibig sabihin, kung anong mga interface ang maaari naming gawin) upang gumana ayon sa konsepto ng ORM. At kung paano gamitin ang mga pondong ito. Hindi inilalarawan ng detalye ang pagpapatupad ng mga tool. Ginagawa nitong posible na gumamit ng iba't ibang mga pagpapatupad para sa isang detalye. Maaari mong pasimplehin ito at sabihin na ang isang detalye ay isang paglalarawan ng API. Ang teksto ng detalye ng JPA ay matatagpuan sa website ng Oracle: " JSR 338: JavaTM Persistence API ". Samakatuwid, upang magamit ang JPA, kailangan namin ng ilang pagpapatupad kung saan gagamitin namin ang teknolohiya. Ang mga pagpapatupad ng JPA ay tinatawag ding JPA Provider. Isa sa mga pinakakilalang pagpapatupad ng JPA ay ang Hibernate . Samakatuwid, iminumungkahi kong isaalang-alang ito.
JPA: Panimula sa Teknolohiya - 3

Paglikha ng isang Proyekto

Dahil ang JPA ay tungkol sa Java, kakailanganin namin ng isang proyekto sa Java. Maaari naming manu-manong gawin ang istraktura ng direktoryo sa aming sarili at idagdag ang mga kinakailangang aklatan sa aming sarili. Ngunit mas maginhawa at tama ang paggamit ng mga system para sa pag-automate ng pagpupulong ng mga proyekto (i.e., sa esensya, ito ay isang programa lamang na mamamahala sa pagpupulong ng mga proyekto para sa amin. Lumikha ng mga direktoryo, magdagdag ng mga kinakailangang aklatan sa classpath, atbp. .). Ang isang ganoong sistema ay Gradle. Maaari kang magbasa ng higit pa tungkol sa Gradle dito: " Isang Maikling Panimula sa Gradle ". Tulad ng alam natin, ang pagpapagana ng Gradle (ibig sabihin, ang mga bagay na magagawa nito) ay ipinapatupad gamit ang iba't ibang Gradle Plugin. Gamitin natin ang Gradle at ang plugin na " Gradle Build Init Plugin ". Patakbuhin natin ang utos:

gradle init --type java-application
Gagawin ni Gradle ang kinakailangang istraktura ng direktoryo para sa amin at gagawa ng pangunahing deklaratibong paglalarawan ng proyekto sa build script build.gradle. Kaya, mayroon kaming isang aplikasyon. Kailangan nating isipin kung ano ang gusto nating ilarawan o imodelo sa ating aplikasyon. Gumamit tayo ng ilang tool sa pagmomodelo, halimbawa: app.quickdatabasediagrams.com JPA: Panimula sa Teknolohiya - 4 Dito nararapat na sabihin na ang aming inilarawan ay ang aming "modelo ng domain." Ang isang domain ay isang "subject area". Sa pangkalahatan, ang domain ay "pagmamay-ari" sa Latin. Noong Middle Ages, ito ang tawag sa mga lugar na pag-aari ng mga hari o pyudal lords. At sa Pranses ito ay naging salitang "domaine", na isinasalin lamang bilang "lugar". Kaya inilarawan namin ang aming "modelo ng domain" = "modelo ng paksa". Ang bawat elemento ng modelong ito ay ilang uri ng "essence", isang bagay mula sa totoong buhay. Sa aming kaso, ito ay mga entity: Kategorya ( Category), Paksa ( Topic). Gumawa tayo ng isang hiwalay na pakete para sa mga entity, halimbawa sa modelo ng pangalan. At magdagdag tayo ng mga klase ng Java doon na naglalarawan sa mga entity. Sa Java code, ang mga naturang entity ay isang regular na POJO , na maaaring ganito ang hitsura:
public class Category {
    private Long id;
    private String title;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}
Gayahin natin ang mga nilalaman ng klase at lumikha ng isang klase sa pamamagitan ng pagkakatulad Topic. Mag-iiba lamang siya sa kung ano ang alam niya tungkol sa kategorya kung saan siya nabibilang. Samakatuwid, magdagdag tayo Topicng field ng kategorya at mga pamamaraan para sa pagtatrabaho dito sa klase:
private Category category;

public Category getCategory() {
	return category;
}

public void setCategory(Category category) {
	this.category = category;
}
Ngayon ay mayroon na kaming Java application na may sariling modelo ng domain. Ngayon ay oras na upang simulan ang pagkonekta sa proyekto ng JPA.
JPA: Panimula sa Teknolohiya - 5

Pagdaragdag ng JPA

Kaya, gaya ng naaalala natin, ang ibig sabihin ng JPA ay may ise-save tayo sa database. Samakatuwid, kailangan namin ng isang database. Upang gumamit ng koneksyon sa database sa aming proyekto, kailangan naming magdagdag ng isang dependency library upang kumonekta sa database. Tulad ng naaalala namin, ginamit namin ang Gradle, na lumikha ng build script para sa amin build.gradle. Sa loob nito ay ilalarawan namin ang mga dependency na kailangan ng aming proyekto. Ang mga dependency ay ang mga library na kung wala ang aming code ay hindi gagana. Magsimula tayo sa isang paglalarawan ng dependency sa pagkonekta sa database. Ginagawa namin ito sa parehong paraan na gagawin namin kung nagtatrabaho lang kami sa JDBC:

dependencies {
	implementation 'com.h2database:h2:1.4.199'
Ngayon ay mayroon na tayong database. Maaari na kaming magdagdag ng isang layer sa aming application na responsable para sa pagmamapa ng aming mga bagay sa Java sa mga konsepto ng database (mula sa Java hanggang SQL). Tulad ng naaalala namin, gagamit kami ng isang pagpapatupad ng detalye ng JPA na tinatawag na Hibernate para dito:

dependencies {
	implementation 'com.h2database:h2:1.4.199'
	implementation 'org.hibernate:hibernate-core:5.4.2.Final'
Ngayon kailangan nating i-configure ang JPA. Kung babasahin natin ang detalye at seksyong "8.1 Persistence Unit", malalaman natin na ang Persistence Unit ay ilang uri ng kumbinasyon ng mga configuration, metadata at entity. At para gumana ang JPA, kailangan mong ilarawan ang kahit isang Persistence Unit sa configuration file, na tinatawag na persistence.xml. Ang lokasyon nito ay inilarawan sa detalye ng kabanata na "8.2 Persistence Unit Packaging". Ayon sa seksyong ito, kung mayroon tayong Java SE na kapaligiran, dapat nating ilagay ito sa ugat ng direktoryo ng META-INF.
JPA: Panimula sa Teknolohiya - 6
Kopyahin natin ang nilalaman mula sa halimbawang ibinigay sa detalye ng JPA sa " 8.2.1 persistence.xml file" kabanata:
<persistence>
	<persistence-unit name="JavaRush">
        <description>Persistence Unit For test</description>
        <class>hibernate.model.Category</class>
        <class>hibernate.model.Topic</class>
    </persistence-unit>
</persistence>
Pero hindi ito sapat. Kailangan nating sabihin kung sino ang ating JPA Provider, i.e. isa na nagpapatupad ng detalye ng JPA:
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
Ngayon, magdagdag tayo ng mga setting ( properties). Ang ilan sa mga ito (nagsisimula sa javax.persistence) ​​ay karaniwang mga configuration ng JPA at inilalarawan sa detalye ng JPA sa seksyong "8.2.1.9 na mga katangian". Ang ilang configuration ay partikular sa provider (sa aming kaso, nakakaapekto ang mga ito sa Hibernate bilang Jpa Provider. Magiging ganito ang hitsura ng aming block ng mga setting:
<properties>
    <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
    <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE" />
    <property name="javax.persistence.jdbc.user" value="sa" />
    <property name="javax.persistence.jdbc.password" value="" />
    <property name="hibernate.show_sql" value="true" />
    <property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
Ngayon ay mayroon na tayong JPA-compatible config persistence.xml, mayroong JPA provider na Hibernate at mayroong H2 database, at mayroon ding 2 klase na modelo ng domain natin. Sa wakas, gawin natin itong lahat. Sa catalog /test/java, ang aming Gradle ay nakabuo ng isang template para sa mga Unit test at tinawag itong AppTest. Gamitin natin ito. Gaya ng nakasaad sa "7.1 Persistence Contexts" na kabanata ng JPA specification, ang mga entity sa JPA world ay nakatira sa isang puwang na tinatawag na Persistence Context. Ngunit hindi kami direktang gumagana sa Konteksto ng Pagtitiyaga. Para dito ginagamit namin Entity Managero "entity manager". Siya ang nakakaalam tungkol sa konteksto at kung anong mga nilalang ang nakatira doon. Nakikisalamuha kami sa Entity Manager'om. Kung gayon ang natitira na lang ay upang maunawaan kung saan natin makukuha ang isang ito Entity Manager? Ayon sa kabanata "7.2.2 Pagkuha ng Application-managed Entity Manager" ng detalye ng JPA, dapat nating gamitin ang EntityManagerFactory. Samakatuwid, hawakan natin ang detalye ng JPA at kumuha ng halimbawa mula sa kabanata na "7.3.2 Pagkuha ng Entity Manager Factory sa isang Java SE Environment" at i-format ito sa anyo ng isang simpleng Unit test:
@Test
public void shouldStartHibernate() {
	EntityManagerFactory emf = Persistence.createEntityManagerFactory( "JavaRush" );
	EntityManager entityManager = emf.createEntityManager();
}
Ipapakita na ng pagsubok na ito ang error na "Unrecognized JPA persistence.xml XSD version." Ang dahilan ay persistence.xmlkailangan mong tukuyin nang tama ang schema na gagamitin, gaya ng nakasaad sa detalye ng JPA sa seksyong "8.3 persistence.xml Schema":
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
             version="2.2">
Bilang karagdagan, ang pagkakasunud-sunod ng mga elemento ay mahalaga. Samakatuwid, providerdapat itong tukuyin bago ilista ang mga klase. Pagkatapos nito, matagumpay na tatakbo ang pagsubok. Nakumpleto na namin ang direktang koneksyon ng JPA. Bago tayo magpatuloy, isipin natin ang mga natitirang pagsubok. Ang bawat isa sa aming mga pagsubok ay mangangailangan EntityManager. Siguraduhin natin na ang bawat pagsubok ay may sariling EntityManagersa simula ng pagpapatupad. Bilang karagdagan, gusto naming maging bago ang database sa bawat oras. Dahil sa ang katunayan na ginagamit namin inmemoryang opsyon, ito ay sapat na upang isara EntityManagerFactory. Ang paglikha Factoryay isang mamahaling operasyon. Ngunit para sa mga pagsubok ito ay makatwiran. Pinapayagan ka ng JUnit na tukuyin ang mga pamamaraan na isasagawa bago (Bago) at pagkatapos (Pagkatapos) ng pagpapatupad ng bawat pagsubok:
public class AppTest {
    private EntityManager em;

    @Before
    public void init() {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory( "JavaRush" );
        em = emf.createEntityManager();
    }

    @After
    public void close() {
        em.getEntityManagerFactory().close();
        em.close();
    }
Ngayon, bago magsagawa ng anumang pagsubok, isang bago ang gagawin EntityManagerFactory, na mangangailangan ng paglikha ng isang bagong database, dahil hibernate.hbm2ddl.autoay may kahulugan create. At mula sa bagong pabrika ay kukuha tayo ng bago EntityManager.
JPA: Panimula sa Teknolohiya - 7

Mga entidad

Tulad ng naaalala namin, gumawa kami dati ng mga klase na naglalarawan sa aming modelo ng domain. Nasabi na natin na ito ang ating mga “essence”. Ito ang Entity na aming pamamahalaan gamit ang EntityManager. Sumulat tayo ng isang simpleng pagsubok upang mai-save ang kakanyahan ng isang kategorya:
@Test
public void shouldPersistCategory() {
	Category cat = new Category();
	cat.setTitle("new category");
	// JUnit обеспечит тест свежим EntityManager'ом
	em.persist(cat);
}
Ngunit ang pagsubok na ito ay hindi gagana kaagad, dahil... makakatanggap kami ng iba't ibang mga error na makakatulong sa aming maunawaan kung ano ang mga entity:
  • Unknown entity: hibernate.model.Category
    Bakit hindi maintindihan ng Hibernate kung ano Categoryito entity? Ang bagay ay ang mga entidad ay dapat na inilarawan ayon sa pamantayan ng JPA.
    Ang mga klase ng entity ay dapat na may anotasyon kasama ng anotasyon @Entity, gaya ng nakasaad sa kabanata "2.1 Ang Klase ng Entity" ng detalye ng JPA.

  • No identifier specified for entity: hibernate.model.Category
    Dapat ay may natatanging identifier ang mga entity na maaaring gamitin upang makilala ang isang record mula sa isa pa.
    Ayon sa kabanata na "2.4 Primary Keys and Entity Identity" ng JPA specification, "Ang bawat entity ay dapat magkaroon ng pangunahing key", i.e. Ang bawat entity ay dapat may "pangunahing susi". Ang nasabing pangunahing key ay dapat na tinukoy ng anotasyon@Id

  • ids for this class must be manually assigned before calling save()
    Ang ID ay dapat nanggaling sa kung saan. Maaari itong tukuyin nang manu-mano, o maaari itong awtomatikong makuha.
    Samakatuwid, gaya ng ipinahiwatig sa mga kabanata na "11.2.3.3 GeneratedValue" at "11.1.20 GeneratedValue Annotation", maaari naming tukuyin ang anotasyon @GeneratedValue.

Kaya para maging entity ang klase ng kategorya, dapat nating gawin ang mga sumusunod na pagbabago:
@Entity
public class Category {
    @Id
    @GeneratedValue
    private Long id;
Bilang karagdagan, ipinapahiwatig ng anotasyon @Idkung alin ang gagamitin Access Type. Maaari kang magbasa nang higit pa tungkol sa uri ng pag-access sa detalye ng JPA, sa seksyong "2.3 Uri ng Pag-access". Sa madaling sabi, dahil... tinukoy namin @Idsa itaas ng field ( field), pagkatapos ay magiging default ang uri ng access field-based, hindi property-based. Samakatuwid, ang tagapagbigay ng JPA ay magbabasa at mag-imbak ng mga halaga nang direkta mula sa mga patlang. Kung inilagay namin @Idsa itaas ng getter, property-basedgagamitin ang access, i.e. sa pamamagitan ng getter at setter. Kapag nagpapatakbo ng pagsubok, nakikita rin namin kung anong mga kahilingan ang ipinadala sa database (salamat sa opsyon hibernate.show_sql). Pero kapag nag-iipon, wala tayong nakikitang insert's. Lumalabas na wala talaga kaming nailigtas? Pinapayagan ka ng JPA na i-synchronize ang konteksto ng pagtitiyaga at ang database gamit ang pamamaraan flush:
entityManager.flush();
Ngunit kung ipapatupad natin ito ngayon, magkakaroon tayo ng error: walang nagaganap na transaksyon . At ngayon ay oras na para malaman kung paano ginagamit ng JPA ang mga transaksyon.
JPA: Panimula sa Teknolohiya - 8

Mga Transaksyon ng JPA

Tulad ng naaalala natin, ang JPA ay batay sa konsepto ng konteksto ng pagtitiyaga. Ito ang lugar kung saan nakatira ang mga entity. At pinamamahalaan namin ang mga entity sa pamamagitan ng EntityManager. Kapag isinagawa namin ang command persist, inilalagay namin ang entity sa konteksto. Mas tiyak, sinasabi namin EntityManagerna kailangan itong gawin. Ngunit ang kontekstong ito ay ilan lamang sa lugar ng imbakan. Tinatawag din itong "first level cache". Ngunit kailangan itong konektado sa database. Ang command flush, na dati ay nabigo nang may error, ay nagsi-synchronize ng data mula sa persistence context sa database. Ngunit nangangailangan ito ng transportasyon at ang transportasyong ito ay isang transaksyon. Inilalarawan ang mga transaksyon sa JPA sa seksyong "7.5 Controlling Transactions" ng detalye. Mayroong isang espesyal na API para sa paggamit ng mga transaksyon sa JPA:
entityManager.getTransaction().begin();
entityManager.getTransaction().commit();
Kailangan naming magdagdag ng pamamahala ng transaksyon sa aming code, na tumatakbo bago at pagkatapos ng mga pagsubok:
@Before
public void init() {
	EntityManagerFactory emf = Persistence.createEntityManagerFactory( "JavaRush" );
	em = emf.createEntityManager();
	em.getTransaction().begin();
}
@After
public void close() {
	if (em.getTransaction().isActive()) {
		em.getTransaction().commit();
        }
	em.getEntityManagerFactory().close();
	em.close();
}
Pagkatapos magdagdag, makikita natin sa insert log ang isang expression sa SQL na wala pa noon:
JPA: Panimula sa Teknolohiya - 9
Ang mga pagbabagong naipon sa EntityManagertransaksyon ay ginawa (nakumpirma at na-save) sa database. Subukan nating hanapin ang ating kakanyahan. Gumawa tayo ng pagsubok para maghanap ng entity sa pamamagitan ng ID nito:
@Test
public void shouldFindCategory() {
	Category cat = new Category();
	cat.setTitle("test");
	em.persist(cat);
	Category result = em.find(Category.class, 1L);
	assertNotNull(result);
}
Sa kasong ito, matatanggap namin ang entity na dati naming na-save, ngunit hindi namin makikita ang SELECT query sa log. At lahat ay nakabatay sa sinasabi namin: "Entity Manager, pakihanap sa akin ang Category entity na may ID=1." At ang entity manager ay unang tumingin sa konteksto nito (gumagamit ng isang uri ng cache), at kung hindi niya ito mahanap, ito ay pupunta upang tumingin sa database. Ito ay nagkakahalaga ng pagpapalit ng ID sa 2 (walang ganoong bagay, na-save lamang namin ang 1 instance), at makikita namin na SELECTang kahilingan ay lilitaw. Dahil walang nakitang entity sa konteksto at EntityManagersinusubukan ng database na maghanap ng entity. May iba't ibang command na magagamit natin para kontrolin ang estado ng isang entity sa konteksto. Ang paglipat ng isang entity mula sa isang estado patungo sa isa pa ay tinatawag na ikot ng buhay ng entidad - lifecycle.
JPA: Panimula sa Teknolohiya - 10

Ikot ng Buhay ng Entity

Ang ikot ng buhay ng mga entity ay inilarawan sa detalye ng JPA sa kabanata na "3.2 Ikot ng Buhay ng Entity Instance". kasi ang mga entity ay nabubuhay sa isang konteksto at kinokontrol ng EntityManager, pagkatapos ay sinasabi nila na ang mga entidad ay kinokontrol, i.e. pinamamahalaan. Tingnan natin ang mga yugto ng buhay ng isang entidad:
// 1. New or Transient (временный)
Category cat = new Category();
cat.setTitle("new category");
// 2. Managed or Persistent
entityManager.persist(cat);
// 3. Транзакция завершена, все сущности в контексте detached
entityManager.getTransaction().begin();
entityManager.getTransaction().commit();
// 4. Сущность изымаем из контекста, она становится detached
entityManager.detach(cat);
// 5. Сущность из detached можно снова сделать managed
Category managed = entityManager.merge(cat);
// 6. И можно сделать Removed. Интересно, что cat всё равно detached
entityManager.remove(managed);
At narito ang isang diagram upang pagsama-samahin ito:
JPA: Panimula sa Teknolohiya - 11
JPA: Panimula sa Teknolohiya - 12

Pagmamapa

Sa JPA maaari nating ilarawan ang mga ugnayan ng mga entity sa pagitan ng bawat isa. Tandaan natin na tiningnan na natin ang mga ugnayan ng mga entity sa pagitan ng isa't isa noong hinarap natin ang modelo ng ating domain. Pagkatapos ay ginamit namin ang quickdatabasediagrams.com na mapagkukunan :
JPA: Panimula sa Teknolohiya - 13
Ang pagtatatag ng mga koneksyon sa pagitan ng mga entity ay tinatawag na mapping o association (Association Mappings). Ang mga uri ng asosasyon na maaaring itatag gamit ang JPA ay ipinakita sa ibaba:
JPA : Panimula sa Teknolohiya - 14
Tingnan natin ang isang entity Topicna naglalarawan ng isang paksa. Ano ang masasabi natin tungkol sa saloobin Topicsa Category? Marami Topicang mapabilang sa isang kategorya. Samakatuwid, kailangan natin ng isang samahan ManyToOne. Ipahayag natin ang relasyong ito sa JPA:
@ManyToOne
@JoinColumn(name = "category_id")
private Category category;
Upang matandaan kung aling mga anotasyon ang ilalagay, maaari mong tandaan na ang huling bahagi ay may pananagutan para sa field sa itaas kung saan nakasaad ang anotasyon. ToOne- tiyak na halimbawa. ToMany- mga koleksyon. Ngayon ang aming koneksyon ay one-way. Gawin natin itong two-way na komunikasyon. Dagdagan natin Categoryang kaalaman tungkol sa lahat Topicna kasama sa kategoryang ito. Dapat itong magtapos sa ToMany, dahil mayroon tayong listahan Topic. Iyon ay, ang saloobin "Sa marami" na mga paksa. Ang tanong ay nananatili - OneToManyo ManyToMany:
JPA: Panimula sa Teknolohiya - 15
Ang isang magandang sagot sa parehong paksa ay mababasa dito: " Ipaliwanag ang ORM oneToMany, manyToMany relation tulad ng limang taon ako ". Kung ang isang kategorya ay may koneksyon sa ToManymga paksa, ang bawat isa sa mga paksang ito ay maaaring magkaroon lamang ng isang kategorya, kung gayon ito ay magiging One, kung hindi man Many. Kaya ang Categorylistahan ng lahat ng mga paksa ay magiging ganito:
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "topic_id")
private Set<Topic> topics = new HashSet<>();
At huwag nating kalimutang Categorymagsulat ng getter para makakuha ng listahan ng lahat ng paksa:
public Set<Topic> getTopics() {
	return this.topics;
}
Ang mga bidirectional na relasyon ay isang napakahirap na bagay na awtomatikong subaybayan. Samakatuwid, inililipat ng JPA ang responsibilidad na ito sa developer. Ang ibig sabihin nito para sa amin ay kapag kami ay nagtatag ng isang entity Topicna relasyon sa Category, dapat naming tiyakin ang pagkakapare-pareho ng data sa aming sarili. Ginagawa ito nang simple:
public void setCategory(Category category) {
	category.getTopics().add(this);
	this.category = category;
}
Sumulat tayo ng isang simpleng pagsubok upang suriin:
@Test
public void shouldPersistCategoryAndTopics() {
	Category cat = new Category();
	cat.setTitle("test");
	Topic topic = new Topic();
	topic.setTitle("topic");
	topic.setCategory(cat);
 	em.persist(cat);
}
Ang pagmamapa ay isang buong hiwalay na paksa. Bilang bahagi ng pagsusuri na ito, ito ay nagkakahalaga ng pag-unawa sa kung ano ang paraan na ito ay nakakamit. Maaari kang magbasa nang higit pa tungkol sa pagmamapa dito:
JPA : Panimula sa Teknolohiya - 16

JPQL

Ipinakilala ng JPA ang isang kawili-wiling tool - mga query sa Java Persistence Query Language. Ang wikang ito ay katulad ng SQL, ngunit gumagamit ng Java object model kaysa sa mga SQL table. Tingnan natin ang isang halimbawa:
@Test
public void shouldPerformQuery() {
	Category cat = new Category();
	cat.setTitle("query");
	em.persist(cat);
	Query query = em.createQuery("SELECT c from Category c WHERE c.title = 'query'");
 	assertNotNull(query.getSingleResult());
}
Gaya ng nakikita natin, sa query ay gumamit kami ng reference sa isang entity Categoryat hindi isang table. At gayundin sa larangan ng entity na ito title. Nagbibigay ang JPQL ng maraming kapaki-pakinabang na tampok at nararapat sa sarili nitong artikulo. Higit pang mga detalye ay matatagpuan sa pagsusuri:
JPA : Panimula sa Teknolohiya - 17

Criteria API

At sa wakas, gusto kong hawakan ang Criteria API. Ipinakilala ng JPA ang isang dynamic na tool sa pagbuo ng query. Halimbawa ng paggamit ng Criteria API:
@Test
public void shouldFindWithCriteriaAPI() {
	Category cat = new Category();
	em.persist(cat);
	CriteriaBuilder cb = em.getCriteriaBuilder();
	CriteriaQuery<Category> query = cb.createQuery(Category.class);
	Root<Category> c = query.from(Category.class);
	query.select(c);
	List<Category> resultList = em.createQuery(query).getResultList();
	assertEquals(1, resultList.size());
}
Ang halimbawang ito ay katumbas ng pagsasagawa ng kahilingang " SELECT c FROM Category c". Ang Criteria API ay isang mahusay na tool. Maaari mong basahin ang higit pa tungkol dito:

Konklusyon

Tulad ng nakikita natin, ang JPA ay nagbibigay ng isang malaking bilang ng mga tampok at tool. Ang bawat isa sa kanila ay nangangailangan ng karanasan at kaalaman. Kahit na sa loob ng balangkas ng pagsusuri ng JPA, hindi posibleng banggitin ang lahat, hindi banggitin ang isang detalyadong pagsisid. Pero sana matapos itong basahin, naging mas malinaw kung ano ang ORM at JPA, kung paano ito gumagana at kung ano ang maaaring gawin dito. Well, para sa isang meryenda nag-aalok ako ng iba't ibang mga materyales: #Viacheslav
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION