JavaRush /Java блогу /Random-KY /JPA субъектилери жана DB мамилелери
Nikita Koliadin
Деңгээл
Днепр

JPA субъектилери жана DB мамилелери

Группада жарыяланган

JPA Entities && DB Relationships

Кайырлы күн, кесиптештер!
JPA субъектилери жана DB мамилелери - 1
Бул материал маалымат базаларын уюштуруу (мындан ары жөн гана МБ - "Маалыматтар базасы"), Объект-Реляциялык Карталоо кандайча иштээри (мындан ары жөн гана ORM ) жана анын Hibernate/JPA сыяктуу ишке ашырылышы жөнүндө минималдуу бorми бар адамдар үчүн арналган. . Эгер сиз бул менен тааныш эмес болсоңуз, мен сизге JDBC менен баштоону кеңеш берем , андан кийин гана ORM моделине өтүңүз. Мен сизге эскерттим жана бул макаланы туура даярданбай окуп чыккандан кийин сиздин психикаңыз үчүн жоопкерчorк тартпайм! :) Баарын ирети менен чече баштайлы. Биринчиден, биз бир аз теорияга тереңдеп киребиз. Экинчиден, биз муну ар бир адамдын сүйүктүү Javaсында кантип жасоону чечебиз. Ошондой эле биз сиздер менен долбоордун алдамчылык баракчасын жазабыз, ал тема боюнча биздин түшүнүгүбүздү бекемдейт жана КАНТИП карта түзүү керектиги үчүн шаблон катары кызмат кылат . Ошентип, келгиле!

Entity деген эмне?

Объект – бул чыныгы жашоодон алынган an object (мисалы, унаа) анын атрибуттары (эшиктер, Дөңгөлөктөр , мотор). DB Entity: Бул учурда, биздин уюм МБда сакталат, бардыгы жөнөкөй. Машинаны эмне үчүн жана кантип маалымат базасына киргизебиз - биз аны кийинчерээк карап чыгабыз.

DB мамилелери деген эмне?

Узак убакыт мурун, алыскы падышалыкта реляциялык МБ түзүлгөн . Бул МБда маалыматтар table түрүндө берилген. Бирок бул үстөлдөрдү өз ара байланыштыруунун механизмин түзүү керек экени Шректен келген эшекке да түшүнүктүү болду . Натыйжада, 4 DB мамилелер пайда болду :
  1. Бирге бир
  2. Бирден-көпкө
  3. Көптөгөн-Бирге
  4. Көптөн көпкө
Эгерде сиз мунун баарын биринчи жолу көрүп жатсаңыз, мен сизге дагы бир жолу эскертем - бул мындан да жаман болот: сейилдөө жөнүндө ойлонуңуз. Биз бул мамилелердин баарын бир мисал менен талдап, алардын ортосундагы айырманы түшүнөбүз.

Коркунучтуу мисал

Бизде 5 бутактан турган бир долбоор болот: мастер, ал жерде долбоордун сүрөттөлүшү жана ар бир МБ байланышы үчүн 1 бутак болот. Ар бир фorалда МБ түзүү жана аны тесттик маалыматтар менен толтуруу үчүн SQL скрипттери жана annotation картасы менен Entity классы болот. Ошондой эле ар бир бутак үчүн Күтүү конфигурация файлы болот. Булут ДБнын же тышкы МБнын айрым аспектилерине алаксып калбоо үчүн мен долбоор үчүн H2 орнотулган МБны колдоном . Шилтемеге өтүү менен, чаң соргучуңузга H2 DB орнотуңуз. Мен ар бир кадамды 1 бутакта сүрөттөп берем, калгандары жөн гана негизги пункттар. Акырында биз жыйынтыктап беребиз. Go. Бул менин долбоордун башкы бутагына шилтеме.

Бирден-бир мамиле

Фorалга шилтеме бул жерде .
  1. Биздин долбоорго H2 DB туташтыруу керек. Бул жерде биз DB жана башка нерселер менен ыңгайлуу иштөө үчүн Ultimate IDEA керек экендигин баса белгилешибиз керек. Эгер сизде мурунтан эле бар болсо, анда DB байланышына түз өтүңүз. Маалыматтар базасына өтүңүз жана скриншоттогудай кылыңыз:

    JPA Entities and DB Relationships - 2

    Андан кийин биз DB орнотууларына өтөбүз. Сиз өзүңүздүн маалыматтарыңызды, жада калса DBMSңызды киргизе аласыз; Кайталап айтам, мен жөнөкөйлүк үчүн H2 DB колдоном.

    JPA Entities and DB Relationships - 3

    Андан кийин, схеманы орнотобуз. Бул кадам милдеттүү эмес, бирок МБда бир нече схемаларыңыз болсо сунушталат.

    JPA Entities and DB Relationships - 4

    Орнотууларды колдонуңуз, акырында биз төмөнкүдөй нерсени алышыбыз керек:

    JPA Entities and DB Relationships - 5
  2. Биз маалымат базасын түздүк жана ага IDEAдан кирүү мүмкүнчүлүгүн конфигурацияладык. Эми сиз анда tableларды түзүп, аны кээ бир маалыматтар менен толтурушуңуз керек. Мисалы, мен эки an objectти алам: Author жана Китеп. Китептин автору болушу мүмкүн, бир нече автору болушу мүмкүн же бирөөсү жок болушу мүмкүн. Бул мисалда биз байланыштардын бардык түрлөрүн түзөбүз. Бирок бул учурда - Бирден-бир мамиле. Келгиле, DB Таблицаларын түзгөн тиешелүү скрипт түзөлү :

    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. Биздин tableларыбыздын диаграммасын карап көрөлү. Бул үчүн, биздин МБдагы RMB:

    JPA Entities and DB Relationships - 9

    Натыйжа:

    JPA Entities and DB Relationships - 10

    UML диаграммасында биз бардык негизги ачкычтарды жана чет өлкөлүк ачкычтарды көрө алабыз, ошондой эле биздин tableлардын ортосундагы байланышты көрөбүз.

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

    Дегеним, эмне болот? Бир tableнын an objectиси башкасынын бир an objectисине байланыштуу болгондо (же BOOK_IDден NOT NULL алынып салынса, такыр тиешеси жок) бирден-бир байланыш керек. Биздин мисалда бир китептин бир автору болушу КЕРЕК. Башка жол жок.

  5. Эми эң кызыгы Java классын DB an objectилери менен кантип туташтыруу керек? Өтө жөнөкөй. Китеп жана 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. Класстагы бардык талаалар МБ an objectинин атрибуттарын кайталайт.
  2. @Data (Lombok'тан ) ар бир талаа үчүн алуучу жана орнотуучу түзүлөт, барабар, хэшcode жокко чыгарылат жана toString ыкмасы түзүлөт дейт.
  3. @Entity бул класстын an object экенин жана DB an objectиси менен байланышканын айтат.
  4. @DynamicInsert жана @DynamicUpdate динамикалык кыстармалар жана жаңыртуулар МБда аткарылат деп айтышат. Булар ТУУРА топтоштурууга ээ болуу үчүн сизге пайдалуу боло турган тереңирээк күтүү жөндөөлөрү.
  5. @Table (аты = "AUTHOR") Book классын DB AUTHOR tableсына байланыштырат.
  6. @Id бул талаа негизги ачкыч экенин айтат.
  7. @GeneratedValue (стратегия = GenerationType.IDENTITY) – негизги ачкыч муун стратегиясы.
  8. @Column (аты = "ID", null = false) талааны DB атрибуту менен байланыштырат, ошондой эле берилген DB талаасы нөл болушу мүмкүн эмес экенин айтат. Бул an objectтерден tableларды түзүүдө да пайдалуу. Биз азыр долбоорубузду кантип түзүп жатканыбызга тескери процесс, бул бирдиктин тесттери үчүн тесттик МБларда керек.
  9. @OneToOne берилген талаа Бирден-бир мамилелер талаасы экенин айтат.
  10. @JoinColumn (аты = "BOOK_ID", уникалдуу = чын, null = false) - BOOK_ID тилкеси түзүлөт, ал уникалдуу жана нөл эмес.
Арткы жагында ( Китеп классында ) биз да Бирден-бир байланышты түзүп, карта түзүлүүчү талааны көрсөтүшүбүз керек. @OneToOne(mappedBy = "book") - бул мисалда бул Author классынын китеп талаасы. JPA аларды өзү байланыштырат. Бир караганда, annotationлардын башаламандыгы бардай сезorши мүмкүн, бирок чындыгында бул абдан ыңгайлуу жана тажрыйба менен сиз аларды ойлонбой туруп эле автоматтык түрдө кошосуз.
  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 - бул биз тандаган DBMS диалектиси.
  2. hibernate.connection.driver_class — Биздин МБнын драйвер классы.
  3. hibernate.connection.url - биздин МБнын utl. Сиз аны биз DB конфигурациялаган биринчи жерден ала аласыз.
  4. hibernate.connection.username - DB колдонуучу аты.
  5. hibernate.connection.password — DB колдонуучу сырсөз.
  6. hibernate.hbm2ddl.auto - tableны түзүү. Жаңыртуу болсо, анда ал мурунтан эле түзүлгөн болсо, жаратпайт, бирок аны жаңылайт.
  7. hibernate.show_sql - DB сурамдарын көрсөтүү керекпи.
  8. hibernate.format_sql - DB сурамдарын форматтоо керекпи. Болбосо, алардын баары бир сапта болот. Мен аны күйгүзүүнү сунуштайм.
  9. hibernate.use_sql_comments - DB сурамдарына комментарийлер. Эгерде бул Кыстаруу болсо, анда суроо-талап Кыстаруу түрүндөгү суроонун үстүнө комментарий жазылат.
  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 - пакеттөө мүмкүнчүлүгүн берет. Сиздин DBMS караңыз: муну баары эле колдой бербейт.
  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

    Мурунку tableдан айырманы сезесизби?

  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

Көп-көп мамилелер

Келгиле, эң кызыктуу мамилеге өтөлү. Бул мамиле адептүүлүк жана уятсыздыктын бардык эрежелери боюнча кошумча table аркылуу түзүлөт. Бирок бул table субъект эмес. Кызык, туурабы? Келгиле, бул бокту карап көрөлү. Фorалга шилтеме бул жерде .
  1. Инициализация сценарийин караңыз , бул жерде кошумча HAS tableсы пайда болот. Биз автордун китеби сыяктуу нерсени алабыз.

    Сценарийди аткаруунун натыйжасында биз төмөнкү tableларды алабыз:

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

    JPA Entities and DB Relationships - 22

    Биздин мисалда бир китепте көп авторлор болушу мүмкүн, ал эми автордун көп китеби болот экен. Алар бири-бирине дал келиши мүмкүн.

  3. Карталоо класстарында класстар ичинде топтомдор болот. Бирок мен айткандай, HAS tableсы субъект эмес.

    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 tableсы менен байланыштырган нерсе. Анда биз эки an objectтин негизги ачкычтарын көрсөтө турган эки атрибуттарды көрсөтөбүз.

    Китеп классы :

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

    Бул жерде биз FetchType жана карта үчүн колдоно турган талааны көрсөтөбүз.

  4. Биздин hibernate.cfg.xml дагы өзгөрүүсүз калды (ар бир бутак үчүн жаңы МБ түзгөнүбүздү эске албайм).

  5. Туруктуулугу:

    JPA Entities and DB Relationships - 23

Дебрифинг

Ошентип, биз DB мамилелеринин түрлөрүн үстүртөн карап чыктык жана аларды ORM моделинде кантип ишке ашырууну чечтик. Биз бардык байланыштарды көрсөткөн сыноо долбоорун жаздык жана гибернация / jpa кантип конфигурациялоону түшүндүк. Фу.

пайдалуу шилтемелер

Менин мурунку макалаларым: PS Текстте каталар жана кемчorктер болушу мүмкүн. PPS Бул макаланы жазып жатканда автор кызыктай бир нерсе чегип жаткан. Конул бурганын учун рахмат!
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION