JavaRush /Java блогы /Random-KK /JPA нысандары және ДҚ қатынастары
Nikita Koliadin
Деңгей
Днепр

JPA нысандары және ДҚ қатынастары

Топта жарияланған

JPA нысандары && ДҚ қатынастары

Қайырлы күн, әріптестер!
JPA нысандары және ДҚ қатынастары - 1
Бұл материал дерекқорларды ұйымдастыру (бұдан әрі жай ғана ДҚ – «Дерекқор»), Объект-Реляциялық картаның қалай жұмыс істейтіні (бұдан әрі жай ғана ORM ) және оның Hibernate сияқты іске асырылуы туралы ең аз білімі бар адамдарға арналған. / JPA . Егер сіз мұнымен таныс болмасаңыз, мен сізге JDBC -тен бастауға кеңес беремін , содан кейін ғана ORM үлгісіне көшіңіз. Мен сізге ескерттім және осы мақаланы дұрыс дайындықсыз оқығаннан кейін сіздің психикаңызға жауапты емеспін! :) Барлығын ретімен шешуді бастайық. Біріншіден, біз теорияға сәл ғана тереңірек үңілеміз. Екіншіден, біз барлығына ұнайтын Java-да бұл істі қалай жасау керектігін анықтаймыз. Сондай-ақ біз сіздермен тақырып бойынша түсінігімізді бекітетін және ҚАЛАЙ КАРСТАУ КЕРЕКТІК үлгісіне қызмет ететін жоба-шестка парағын жазамыз . Ендеше, жасайық!

Entity дегеніміз не?

Нысан - бұл нақты өмірден алынған an object (мысалы, автомобиль), оның атрибуттары бар (есіктер, Дөңгелектер , қозғалтқыш). DB Entity: Бұл жағдайда біздің нысан ДҚ-да сақталады, барлығы қарапайым. Неліктен және қалай біз көлікті дерекқорға енгіземіз - біз оны кейінірек қарастырамыз.

ДҚ қатынасы дегеніміз не?

Ұзақ уақыт бұрын алыс патшалықта реляциялық ДҚ құрылды . Бұл МБ-да деректер кесте түрінде берілген. Бірақ Шректен келген есекке бұл кестелерді өзара байланыстыру механизмін жасау керек екені де түсінікті болды . Нәтижесінде 4 МҚ қатынасы пайда болды :
  1. Бірден
  2. Бірден көпке
  3. Көп-бірге
  4. Көптен-көпке
Егер сіз мұның бәрін бірінші рет көріп отырсаңыз, мен сізге тағы да ескертемін - бұл нашарлайды: серуендеу туралы ойланыңыз. Біз осы қатынастардың барлығын мысал арқылы талдаймыз және олардың арасындағы айырмашылықты түсінеміз.

Қорқынышты мысал

Бізде 5 тармақтан тұратын бір жоба болады: мастер, онда жобаның сипаттамасы болады және әрбір ДҚ қатынасы үшін 1 фorал. Әрбір фorалда ДҚ құруға және оны сынақ деректерімен толтыруға арналған SQL сценарийлері, сонымен қатар annotation салыстыруы бар Entity сыныбы болады. Сондай-ақ әрбір фorал үшін күту күйінің конфигурация файлы болады. Мен бұлттық DB немесе сыртқы ДҚ-ның жеке аспектілеріне алаңдамау үшін жоба үшін H2 ендірілген ДҚ пайдаланамын . Сілтемені орындау арқылы шаңсорғышқа H2 DB орнатыңыз. Мен әрбір қадамды 1 тармақта сипаттаймын, қалғандары тек негізгі нүктелер. Соңында біз қорытындылаймыз. Бар. Бұл менің жобамның негізгі бөліміне сілтеме.

Бірегей қарым-қатынас

Фorалға сілтеме мына жерде .
  1. Біз жобамызға H2 DB қосуымыз керек. Бұл жерде бізге DB және басқа нәрселермен ыңғайлы жұмыс істеу үшін Ultimate IDEA қажет екенін атап өту керек. Егер сізде ол бұрыннан бар болса, тікелей DB қосылымына өтіңіз. «Дерекқор» қойындысына өтіп, скриншоттағыдай орындаңыз:

    JPA Entities and DB Relationships - 2

    Әрі қарай біз ДҚ параметрлеріне көшеміз. Сіз өзіңіздің деректеріңізді, тіпті ДҚБЖ енгізе аласыз; Қайталап айтамын, мен қарапайымдылық үшін H2 DB қолданамын.

    JPA Entities and DB Relationships - 3

    Әрі қарай, схеманы орнатамыз. Бұл қадам міндетті емес, бірақ ДҚ-да бірнеше схемаларыңыз болса ұсынылады.

    JPA Entities and DB Relationships - 4

    Параметрлерді қолданыңыз, соңында біз келесідей нәрсені аламыз:

    JPA Entities and DB Relationships - 5
  2. Біз дерекқорды жасадық және оған IDEA арқылы қол жеткізуді теңшедік. Енді оған кестелер жасап, оны кейбір деректермен толтыру керек. Мысалы, мен екі нысанды аламын: Author және Кітап. Кітаптың авторы болуы мүмкін, бірнеше авторы болуы мүмкін немесе біреуі болмауы мүмкін. Бұл мысалда біз қосылымдардың барлық түрлерін жасаймыз. Бірақ бұл кезде - Бірден-бір қарым-қатынас. ДҚ кестелерін жасайтын сәйкес сценарийді жасайық :

    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)
    );

    Ал оны орындаймыз:

    JPA Entities and DB Relationships - 6

    Консольдегі орындау нәтижесі:

    JPA Entities and DB Relationships - 7

    ДҚ нәтижесі:

    JPA Entities and DB Relationships - 8
  3. Кестелеріміздің сызбасын қарастырайық. Мұны істеу үшін, біздің ДҚ-дағы RMB:

    JPA Entities and DB Relationships - 9

    Нәтиже:

    JPA Entities and DB Relationships - 10

    UML диаграммасында біз барлық негізгі кілттер мен сыртқы кілттерді көре аламыз, сонымен қатар кестелер арасындағы байланысты көреміз.

  4. ДБ-ны сынақ деректерімен толтыратын сценарий жазайық :

    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);

    Айтайын дегенім, не болады? Бір кестенің нысаны екіншісінің бір нысанына қатысты болғанда (немесе BOOK_ID ішінен NOT NULL жойылса, мүлде байланысты емес) бір-бір қатынас қажет. Біздің мысалда бір кітапта бір автор болуы МІНДЕТТІ. Басқа жол жоқ.

  5. Енді ең қызықтысы Java класын ДҚ нысандарымен қалай қосуға болады? Өте оңай. Кітап және Author деген екі сынып құрайық. Мысал қолдана отырып, мен 1 сыныпты және негізгі коммуникациялық өрістерді талдаймын. Мысал ретінде Author класын алайық :

    @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;
    }
Оны ретімен анықтайық:
  1. Сыныптағы барлық өрістер ДҚ нысанының атрибуттарын қайталайды.
  2. @Data ( Lombok тілінен ) әрбір өріс үшін қабылдаушы мен орнатушы жасалатынын, тең, хэшcode қайта анықталатынын және toString әдісі жасалатынын айтады.
  3. @Entity берілген сыныптың нысан екенін және ДҚ нысанымен байланыстырылғанын айтады.
  4. @DynamicInsert және @DynamicUpdate динамикалық кірістірулер мен жаңартулар ДҚ-да орындалатынын айтады. Бұл ДҰРЫС топтамаға ие болу үшін сізге пайдалы болатын тереңірек күту күйінің параметрлері.
  5. @Table (аты = "AUTHOR") Book класын DB AUTHOR кестесімен байланыстырады.
  6. @Id бұл өріс негізгі кілт екенін айтады.
  7. @GeneratedValue (стратегия = GenerationType.IDENTITY) – негізгі кілтті генерациялау стратегиясы.
  8. @Column (аты = «ID», null = false) өрісті ДҚ төлсипатымен байланыстырады, сонымен қатар берілген ДҚ өрісі бос болуы мүмкін емес екенін айтады. Бұл нысандардан кестелерді жасау кезінде де пайдалы. Енді жобамызды қалай жасайтынымызға кері процесс, бұл бірлік сынақтары үшін сынақ ДҚ-ларында қажет.
  9. @OneToOne берілген өрістің Бірден-бір қатынас өрісі екенін айтады.
  10. @JoinColumn (атауы = «BOOK_ID», бірегей = шын, нөлге тең = жалған) - BOOK_ID бағаны жасалады, ол бірегей және бос емес.
Артқы жағында ( Кітап сыныбында ) біз сондай-ақ Бір-бірге қосылым жасап, салыстыру орын алатын өрісті көрсетуіміз керек. @OneToOne(mappedBy = "кітап") - бұл мысалда бұл Author сыныбының кітап өрісі. JPA оларды өзі байланыстырады. Бір қарағанда, annotationлар шатастырылған сияқты көрінуі мүмкін, бірақ іс жүзінде бұл өте ыңғайлы және тәжірибе арқылы сіз оларды ойланбастан автоматты түрде қосасыз.
  1. Енді күту күйін конфигурациялайық. Ол үшін hibernate.cfg.xml файлын жасаңыз:

    <?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>
қасиеттерінің сипаттамасы :
  1. hibernate.dialect - біз таңдаған ДҚБЖ диалектісі.
  2. hibernate.connection.driver_class — Біздің ДҚ драйвер класы.
  3. hibernate.connection.url - біздің ДБ utl. Сіз оны ДБ конфигурациялаған бірінші нүктеден ала аласыз.
  4. hibernate.connection.username - DB пайдаланушы аты.
  5. hibernate.connection.password — МҚ пайдаланушы құпия сөзі.
  6. hibernate.hbm2ddl.auto - кесте құруды орнату. Жаңарту болса, ол әлдеқашан жасалған болса жасамайды, тек жаңартады.
  7. hibernate.show_sql - ДҚ сұрауларын көрсету керек пе.
  8. hibernate.format_sql - ДҚ сұрауларын пішімдеу керек пе. Олай болмаса, олардың барлығы бір жолда болады. Мен оны қосуды ұсынамын.
  9. hibernate.use_sql_comments - ДҚ сұрауларына түсініктеме береді. Егер бұл Кірістіру болса, сұраудың Кірістіру түріне жататындығы туралы сұраудың үстіне түсініктеме жазылады.
  10. hibernate.generate_statistics - журналдарды жасайды. Мен жүйеге кіруді максималды деңгейге орнатуды ұсынамын және ұсынамын. Журналдарды оқу ORM-мен дұрыс жұмыс істеу мүмкіндігін арттырады.
  11. hibernate.jdbc.batch_size — Буманың ең үлкен өлшемі.
  12. hibernate.jdbc.fetch_size — Ең үлкен алу өлшемі.
  13. hibernate.order_inserts - динамикалық кірістірулерге мүмкіндік береді.
  14. hibernate.order_updates - динамикалық жаңартуларға мүмкіндік береді.
  15. hibernate.jdbc.batch_versioned_data - топтастыруға мүмкіндік береді. ДҚБЖ қараңыз: мұны бәрі бірдей қолдамайды.
  16. карта жасау класы – біздің нысандарымыз болып табылатын сыныптар. Барлығын тізімдеу керек.
  1. Енді біздің болмысымыз анықталуы керек. Біз мұны табандылық қойындысында тексере аламыз:

    JPA Entities and DB Relationships - 11

    Нәтиже:

    JPA Entities and DB Relationships - 12
  2. Біз сондай-ақ деректерді тағайындауды конфигурациялауымыз керек:

    JPA Entities and DB Relationships - 13 JPA Entities and DB Relationships - 14

    Нәтижелер: Біз бір-бір картаны жасадық. Материал тек ақпараттық мақсаттарға арналған, мәліметтер сілтемелерде берілген.

Бірден көпке қатынас

Фorалға сілтеме мына жерде . Мен мақалада codeты енді орналастырмаймын, себебі ол тым ұзақ. Біз GitHub-тағы барлық codeты қарастырамыз.
  1. Инициализация сценарийін орындау нәтижесінде біз келесіні аламыз:

    JPA Entities and DB Relationships - 15

    Алдыңғы кестеден айырмашылықты сезінесіз бе?

  2. Диаграмма:

    JPA Entities and DB Relationships - 16

    Бірден көпке қатынас – бір автордың бірнеше кітабы болуы мүмкін. Сол жақ элемент бір немесе бірнеше оң жаққа сәйкес келеді.

  3. Карталаудағы айырмашылық annotationлар мен өрістерде болады:

    Author сыныбында өріс пайда болады :

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "author")
    private Set<Book> books;

    Бұл қазірдің өзінде жинақ, өйткені бізде бірнеше кітап болуы мүмкін. @OneToMany көзқарас түрі туралы айтады. FetchType.Lazy егер сұрауда көрсетілмесе, кітаптардың толық тізімін жүктеудің қажеті жоқ дейді. Сондай-ақ, бұл өрісті toString-ге қосуға БОЛМАЙДЫ деп айту керек, әйтпесе StackOverflowError қатесін шеге бастаймыз. Менің сүйікті Ломбок мұнымен айналысады:

    @ToString(exclude = "books")

    Кітап сыныбында біз «Көптен-бірге» кері байланыс жасаймыз:

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "AUTHOR_ID", nullable = false)
    private Author author;

    Мұнда біз «Бірге-көпке» «Көпке-бірге» айнадағы бейне және керісінше деген қорытындыға келдік. Hibernate екі бағытты байланыстар туралы ештеңе білмейтінін атап өткен жөн. Ол үшін бұл екі түрлі байланыс: бірі бір бағытта, екіншісі қарама-қарсы бағытта.

  4. hibernate.cfg.xml ішінде көп ештеңе өзгерген жоқ .

  5. Табандылық:

    JPA Entities and DB Relationships - 17

Көпшілік қатынас

«Көптен-бірге» - «Бірге-көпке» айнадағы бейне болғандықтан, айырмашылықтар аз болады. Фorалға сілтеме мына жерде .
  1. Инициализация сценарийін орындау нәтижесінде біз келесі нәтижені аламыз:

    JPA Entities and DB Relationships - 18
  2. Диаграмма:

    JPA Entities and DB Relationships - 19
  3. Карталаудағы айырмашылық annotationлар мен өрістерде болады:

    Author сыныбында енді жиын жоқ, себебі ол Кітап сыныбына көшті .

  4. hibernate.cfg.xml

  5. Табандылық:

    JPA Entities and DB Relationships - 20

Көптен көпке қатынас

Ең қызықты қарым-қатынасқа көшейік. Бұл қатынас әдептілік пен әдепсіздіктің барлық ережелері бойынша қосымша кесте арқылы жасалады. Бірақ бұл кесте нысан емес. Қызық, иә? Келіңіздер, мына сұмдықты қарастырайық. Фorалға сілтеме мына жерде .
  1. Инициализация сценарийін қараңыз , мұнда қосымша HAS кестесі пайда болады. Біз автордың кітабы сияқты нәрсені аламыз.

    Сценарийді орындау нәтижесінде біз келесі кестелерді аламыз:

    JPA Entities and DB Relationships - 21
  2. Диаграмма:

    JPA Entities and DB Relationships - 22

    Біздің мысалда кітаптың көп авторы болуы мүмкін, ал автордың көп кітабы болуы мүмкін екен. Олар қабаттасуы мүмкін.

  3. Карталау сыныптарында сыныптар ішінде жиынтықтар болады. Бірақ мен айтқанымдай, HAS кестесі нысан емес.

    Author сыныбы :

    @ManyToMany
    @JoinTable(name = "HAS",
            joinColumns = @JoinColumn(name = "AUTHOR_ID", referencedColumnName = "ID"),
            inverseJoinColumns = @JoinColumn(name = "BOOK_ID", referencedColumnName = "ID")
    )
    private Set<Book> books;

    @ManyToMany - қарым-қатынас түрі.

    @JoinTable - бұл атрибутты қосымша HAS кестесімен байланыстыратын нәрсе. Онда біз екі нысанның бастапқы кілттерін көрсететін екі атрибутты көрсетеміз.

    Кітап сыныбы :

    @ManyToMany(fetch = FetchType.LAZY, mappedBy = "books")
    private Set<Author> authors;

    Мұнда біз FetchType түрін және картаны жасау үшін қолданатын өрісті көрсетеміз.

  4. Біздің hibernate.cfg.xml қайтадан өзгеріссіз қалды (әр фorал үшін жаңа ДҚ жасағанымызды ескермеймін).

  5. Табандылық:

    JPA Entities and DB Relationships - 23

Дебрифинг

Сонымен, біз ДҚ қатынастарының түрлерін үстірт қарастырдық және оларды ORM үлгісінде қалай енгізу керектігін анықтадық. Біз барлық қосылымдарды көрсететін сынақ жобасын жаздық және гибернация / jpa қалай конфигурациялау керектігін түсіндік. Фу.

пайдалы сілтемелер

Менің алдыңғы мақалаларым: PS Мәтінде қателер мен кемшіліктер болуы мүмкін. PPS Бұл мақаланы жазу кезінде автор біртүрлі нәрсе темекі шегеді. Назарларыңызға рахмет!
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION