JPA Müəssisələri && DB Əlaqələri
Gününüz xeyir, həmkarlar!Entity nədir?
Müəssisə atributları (qapılar, TƏKƏRLƏR , mühərrik ) olan real həyatdan bir obyektdir (məsələn, avtomobil ) . DB Müəssisəsi: Bu halda bizim qurumumuz DB-də saxlanılır, hər şey sadədir. Maşını niyə və necə verilənlər bazasına qoyduq - daha sonra baxacağıq.DB Əlaqələri nədir?
Uzun müddət əvvəl, uzaq səltənətdə , əlaqəli DB yaradılmışdır . Bu DB-də məlumatlar cədvəllər şəklində təqdim edilmişdir. Amma Şrekdən gələn eşşəyə də aydın idi ki, bu masaları bir-birinə bağlamaq üçün mexanizm yaratmaq lazımdır. Nəticədə 4 DB əlaqəsi meydana çıxdı : Bütün bunları ilk dəfə görürsünüzsə, sizə bir daha xəbərdarlıq edirəm - daha da pisləşəcək: gəzintiyə çıxmağı düşünün. Bütün bu əlaqələri bir nümunə ilə təhlil edəcəyik və aralarındakı fərqi anlayacağıq.Dəhşət nümunəsi
5 filialı olacaq bir layihəmiz olacaq: layihənin təsviri olacaq master və hər bir DB əlaqəsi üçün 1 filial. Hər bir filial verilənlər bazası yaratmaq və onu test məlumatları ilə doldurmaq üçün SQL skriptlərini, üstəlik, annotasiya xəritəsi ilə Müəssisə sinfini ehtiva edəcəkdir. Həmçinin, hər bir filial üçün Hibernate konfiqurasiya faylı olacaq. Bulud DB və ya xarici DB-nin fərdi aspektlərindən yayınmamaq üçün layihə üçün H2 daxil edilmiş DB-dən istifadə edəcəyəm . Linkə daxil olaraq, tozsoranınıza H2 DB quraşdırın. Hər addımı 1 budaqda təsvir edəcəyəm, qalanları sadəcə əsas məqamlardır. Sonda ümumiləşdirəcəyik. Get. Bu mənim layihəmin master filialına keçiddir.Bir-bir Münasibət
Filialın linki burada .-
H2 DB-ni layihəmizə qoşmalıyıq. Burada vurğulamalıyıq ki, DB və digər şeylərlə rahat işləmək üçün Ultimate IDEA lazımdır. Əgər sizdə artıq varsa, onda birbaşa DB bağlantısına keçin. Verilənlər bazası sekmesine keçin və ekran görüntüsündə olduğu kimi edin:
Sonra DB parametrlərinə keçirik. Siz məlumatlarınızı və hətta DBMS-nizi daxil edə bilərsiniz; təkrar edirəm, sadəlik üçün H2 DB-dən istifadə edirəm.
Sonra, dövrəni quraq. Bu addım isteğe bağlıdır, lakin DB-də bir neçə sxeminiz varsa tövsiyə olunur.
Parametrləri tətbiq edin və sonda belə bir şey almalıyıq:
-
Biz verilənlər bazasını yaratdıq və IDEA-dan ona girişi konfiqurasiya etdik. İndi orada cədvəllər yaratmalı və bəzi məlumatlar ilə doldurmalısınız. Məsələn, mən iki varlıq götürəcəyəm: Müəllif və Kitab. Kitabın müəllifi ola bilər, bir neçə müəllifi ola bilər və ya olmaya da bilər. Bu nümunədə biz bütün növ əlaqələr yaradacağıq. Ancaq bu nöqtədə - Bir-bir əlaqə. DB Cədvəllərini yaradan müvafiq skripti yaradaq :
DROP TABLE IF EXISTS PUBLIC.BOOK; CREATE TABLE PUBLIC.BOOK ( ID INTEGER NOT NULL AUTO_INCREMENT, NAME VARCHAR(255) NOT NULL, PRINT_YEAR INTEGER(4) NOT NULL, CONSTRAINT BOOK_PRIMARY_KEY PRIMARY KEY (ID) ); DROP TABLE IF EXISTS PUBLIC.AUTHOR; CREATE TABLE PUBLIC.AUTHOR ( ID INTEGER NOT NULL AUTO_INCREMENT, FIRST_NAME VARCHAR(255) NOT NULL, SECOND_NAME VARCHAR(255) NOT NULL, BOOK_ID INTEGER NOT NULL UNIQUE, CONSTRAINT AUTHOR_PRIMARY_KEY PRIMARY KEY (ID), CONSTRAINT BOOK_FOREIGN_KEY FOREIGN KEY (BOOK_ID) REFERENCES BOOK (ID) );
Və onu icra edək:
Konsolda icra nəticəsi:
DB-də nəticə:
-
Cədvəllərimizin diaqramına baxaq. Bunu etmək üçün, DB-də RMB:
Nəticə:
UML diaqramında biz bütün əsas açarları və xarici açarları görə bilərik, həmçinin cədvəllərimiz arasındakı əlaqəni görürük.
-
DB-ni test məlumatları ilə dolduran bir skript yazaq :
INSERT INTO PUBLIC.BOOK (NAME, PRINT_YEAR) VALUES ('First book', 2010), ('Second book', 2011), ('Third book', 2012); INSERT INTO PUBLIC.AUTHOR (FIRST_NAME, SECOND_NAME, BOOK_ID) VALUES ('Pablo', 'Lambado', 1), ('Pazo', 'Zopa', 2), ('Lika', 'Vika', 3);
Demək istəyirəm ki, nə baş verir? Bir cədvəlin obyekti digərinin bir obyekti ilə əlaqəli olduqda (və ya BOOK_ID-dən NOT NULL silinərsə, heç bir əlaqəsi olmadıqda) bir-bir əlaqə lazımdır. Bizim nümunəmizdə bir kitabın bir müəllifi olmalıdır. Başqa yol yoxdur.
-
İndi ən maraqlısı Java sinifini DB obyektləri ilə necə bağlamaq olar? Çox sadə. Kitab və Müəllif iki sinif yaradaq. Bir nümunədən istifadə edərək, 1-ci sinfi və əsas ünsiyyət sahələrini təhlil edəcəyəm. Nümunə olaraq Müəllif sinfini götürək :
@Data @Entity @DynamicInsert @DynamicUpdate @Table(name = "AUTHOR") public class Author { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "ID", nullable = false) private Long id; @Column(name = "FIRST_NAME", nullable = false) private String firstName; @Column(name = "SECOND_NAME", nullable = false) private String secondName; @OneToOne @JoinColumn(name = "BOOK_ID", unique = true, nullable = false) private Book book; }
- Sinifdəki bütün sahələr DB obyektinin atributlarını təkrarlayır.
- @Data ( Lombok -dan ) deyir ki, hər bir sahə üçün alıcı və təyinedici yaradılacaq, bərabərdir, hashcode ləğv ediləcək və toString metodu yaradılacaq.
- @Entity deyir ki, verilmiş sinif bir varlıqdır və DB obyekti ilə əlaqələndirilir.
- @DynamicInsert və @DynamicUpdate dinamik əlavələrin və yeniləmələrin DB-də yerinə yetiriləcəyini bildirir. Bunlar sizin üçün faydalı olacaq daha dərin Hibernate parametrləridir ki, siz DÜZGÜN yığım əldə edəsiniz.
- @Cədvəl (ad = "AUTHOR") Kitab sinfini DB AUTHOR cədvəlinə bağlayır.
- @Id deyir ki, bu sahə əsas açardır.
- @GeneratedValue (strategiya = GenerationType.IDENTITY) – əsas açar yaratma strategiyası.
- @Column (ad = "ID", null = false) sahəni DB atributu ilə əlaqələndirir və həmçinin verilmiş DB sahəsinin null ola bilməyəcəyini bildirir. Bu, obyektlərdən cədvəllər yaradan zaman da faydalıdır. İndi layihəmizi necə yaratdığımıza əks proses, vahid testləri üçün test DB-lərində lazımdır.
- @OneToOne deyir ki, verilmiş sahə Bir-bir əlaqə sahəsidir.
- @JoinColumn (ad = "BOOK_ID", unikal = doğru, null edilə bilən = false) - unikal və null olmayan BOOK_ID sütunu yaradılacaq.
-
İndi Hibernate rejimini konfiqurasiya edək. Bunu etmək üçün hibernate.cfg.xml faylı yaradın:
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property> <property name="hibernate.connection.driver_class">org.h2.Driver</property> <property name="hibernate.connection.url">jdbc:h2:~/db/onetoone</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password"/> <property name="hibernate.hbm2ddl.auto">update</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <property name="hibernate.use_sql_comments">true</property> <property name="hibernate.generate_statistics">true</property> <property name="hibernate.jdbc.batch_size">50</property> <property name="hibernate.jdbc.fetch_size">50</property> <property name="hibernate.order_inserts">true</property> <property name="hibernate.order_updates">true</property> <property name="hibernate.jdbc.batch_versioned_data">true</property> <mapping class="com.qthegamep.forjavarushpublication2.entity.Book"/> <mapping class="com.qthegamep.forjavarushpublication2.entity.Author"/> </session-factory> </hibernate-configuration>
- hibernate.dialekt seçdiyimiz DBMS-nin dialektidir.
- hibernate.connection.driver_class - DB-nin sürücü sinfi.
- hibernate.connection.url - DB-nin utl. Siz onu DB-ni konfiqurasiya etdiyimiz ilk nöqtədən götürə bilərsiniz.
- hibernate.connection.username - DB istifadəçi adı.
- hibernate.connection.password — DB istifadəçi parolu.
- hibernate.hbm2ddl.auto - cədvəl yaratmağın qurulması. Əgər yenilənirsə, o, artıq yaradılıbsa, yaratmır, ancaq onu yeniləyir.
- hibernate.show_sql - DB sorğularının göstərilib-göstərilməməsi.
- hibernate.format_sql - DB sorğularının formatlaşdırılıb-formatlanmayacağı. Əks təqdirdə, hamısı bir xəttdə olacaq. Mən onu yandırmağı məsləhət görürəm.
- hibernate.use_sql_comments - DB sorğularını şərh edir. Əgər bu Insertdirsə, o zaman sorğunun Insert tipli olması barədə sorğunun üstündə şərh yazılır.
- hibernate.generate_statistics - qeydlər yaradır. Girişi maksimum dərəcədə qurmağı tövsiyə edirəm və tövsiyə edirəm. Qeydləri oxumaq ORM ilə düzgün işləmək şansınızı artıracaq.
- hibernate.jdbc.batch_size — Maksimum toplu ölçüsü.
- hibernate.jdbc.fetch_size — Maksimum gətirmə ölçüsü.
- hibernate.order_inserts - dinamik əlavələrə icazə verir.
- hibernate.order_updates - Dinamik yeniləmələrə imkan verir.
- hibernate.jdbc.batch_versioned_data - paketləşdirməyə imkan verir. DBMS-ə baxın: hamı bunu dəstəkləmir.
- Xəritəçəkmə sinfi - bizim qurumlarımız olan siniflər. Hər şeyi sadalamaq lazımdır.
-
İndi bizim mahiyyətimiz müəyyənləşməlidir. Bunu əzmkarlıq tabında yoxlaya bilərik:
Nəticə:
-
Biz həmçinin təyin datasını konfiqurasiya etməliyik:
Nəticələr: Biz Birə Bir Xəritəçəkmə etdik. Material yalnız məlumat məqsədi daşıyır, təfərrüatlar istinadlardadır.
Bir-çox əlaqə
Filialın linki burada . Artıq çox uzun olduğu üçün kodu məqalədə yerləşdirməyəcəyəm. GitHub-da bütün koda baxırıq.-
İnisializasiya skriptinin icrası nəticəsində aşağıdakıları əldə edirik:
Əvvəlki cədvəllə fərq hiss edirsinizmi?
-
Diaqram:
Bir-çox əlaqə - bir müəllifin bir neçə kitabı ola bilər. Sol obyekt bir və ya daha çox sağa uyğun gəlir.
-
Xəritəçəkmədəki fərq annotasiyalarda və sahələrdə olacaq:
Müəllif sinfində sahə görünür :
@OneToMany(fetch = FetchType.LAZY, mappedBy = "author") private Set<Book> books;
Artıq bir dəstdir, çünki bir neçə kitabımız ola bilər. @OneToMany münasibət növü haqqında danışır. FetchType.Lazy deyir ki, əgər sorğuda göstərilməyibsə, kitabların bütün siyahısını yükləməyimiz lazım deyil. Onu da qeyd etmək lazımdır ki, bu sahə toString-ə əlavə oluna bilməz, əks halda StackOverflowError-u çəkməyə başlayacağıq. Mənim sevimli Lombokum bununla məşğul olur:
@ToString(exclude = "books")
Kitab sinfində biz Çoxdan Birə rəy veririk:
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "AUTHOR_ID", nullable = false) private Author author;
Buradan belə nəticəyə gəlirik ki, Birdən Çoxa Çoxdan Birə və əksinə güzgü şəklidir. Qeyd etmək lazımdır ki, Hibernate iki istiqamətli kommunikasiyalar haqqında heç nə bilmir. Onun üçün bunlar iki fərqli əlaqədir: biri bir istiqamətdə, digəri əks istiqamətdə.
-
hibernate.cfg.xml faylında çox şey dəyişməyib .
-
Davamlılıq:
Çox-bir əlaqə
Çoxdan Birə, Birdən Çoxa güzgü görüntüsü olduğundan, fərqlər az olacaq. Filialın linki burada .-
İnisializasiya skriptinin icrası nəticəsində aşağıdakı nəticəni əldə edirik:
-
Diaqram:
-
Xəritəçəkmədəki fərq annotasiyalarda və sahələrdə olacaq:
Kitab sinfinə keçdiyi üçün Müəllif sinfində artıq dəst yoxdur .
-
Davamlılıq:
Çoxdan Çoxa Münasibət
Ən maraqlı münasibətə keçək. Bu münasibət bütün ədəb və ədəbsizlik qaydalarına görə əlavə cədvəl vasitəsilə yaradılır. Lakin bu cədvəl bir varlıq deyil. Maraqlıdır, hə? Gəlin bu zəhmətə nəzər salaq. Filialın linki burada .-
İnisiallaşdırma skriptinə baxın , burada əlavə HAS cədvəli görünür. Biz müəllif-kitab kimi bir şey alırıq.
Skriptin icrası nəticəsində aşağıdakı cədvəlləri alacağıq:
-
Diaqram:
Bizim nümunəmizdə belə çıxır ki, bir kitabın çoxlu müəllifi ola bilər, müəllifin də çoxlu kitabı ola bilər. Onlar üst-üstə düşə bilər.
-
Xəritəçəkmə siniflərinin siniflər daxilində dəstləri olacaq. Amma dediyim kimi, HAS cədvəli bir varlıq deyil.
Müəllif sinfi :
@ManyToMany @JoinTable(name = "HAS", joinColumns = @JoinColumn(name = "AUTHOR_ID", referencedColumnName = "ID"), inverseJoinColumns = @JoinColumn(name = "BOOK_ID", referencedColumnName = "ID") ) private Set<Book> books;
@ManyToMany bir əlaqə növüdür.
@JoinTable - atributu əlavə HAS cədvəli ilə birləşdirən məhz budur. Orada iki obyektin əsas açarlarına işarə edəcək iki atribut təyin edirik.
Kitab sinfi :
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "books") private Set<Author> authors;
Burada FetchType və xəritə üçün istifadə edəcəyimiz sahəni göstəririk.
-
Bizim hibernate.cfg.xml yenə dəyişməz qaldı (hər filial üçün yeni DB yaratdığımızı nəzərə almıram).
-
Davamlılıq:
Debrifinq
Beləliklə, biz DB əlaqələrinin növlərini səthi şəkildə araşdırdıq və onların ORM modelində necə həyata keçiriləcəyini anladıq. Bütün əlaqələri nümayiş etdirən bir sınaq layihəsi yazdıq və hibernate / jpa-nın necə konfiqurasiya olunacağını anladıq. vay.faydalı bağlantılar
- Əslində layihənin özü
- Bir-bir filial
- Birdən çoxa filial
- Çoxdan birə filial
- Çoxdan çoxa filial
- Oxuyun
- Və oxuyun
GO TO FULL VERSION