Статьи

Отображение XML один-ко-многим в Hibernate

Отношение «один ко многим» гласит, что один экземпляр объекта связан с несколькими экземплярами другого объекта. Другими словами, каждая запись в одной из таблиц связана с несколькими записями в другой таблице.

Давайте посмотрим, как мы можем определить такие отношения в Hibernate с помощью файла сопоставления XML.

1. Диаграмма отношений сущностей

Предполагая, что у нас есть таблицы студентов и отделов, созданные в базе данных, ниже приведена диаграмма отношений сущностей для таблиц студентов и отделов в базе данных MySQL.

ER-диаграмма

2. Maven Зависимость

Давайте сначала настроим файл pom.xml в нашем проекте maven.

Убедитесь, что в наш файл pom.xml добавлены следующие зависимости.

01
02
03
04
05
06
07
08
09
10
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.30</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>4.3.5.Final</version>
</dependency>

3. Настройка конфигурации Hibernate

Убедитесь, что файл hibernate.cfg.xml настроен и добавлен в структуру проекта в classpath.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
<hibernate-configuration>
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/sample_db</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.show_sql">true</property>
  
        <mapping resource="Student.hbm.xml" />
        <mapping resource="Department.hbm.xml" />
    </session-factory>
</hibernate-configuration>

4. Классы сущностей

У нас есть две сущности, участвующие в нашем демонстрационном приложении, студент и отдел, для которого у нас есть две таблицы, существующие в базе данных. Поэтому нам нужно создать классы сущностей, соответствующие этим таблицам.

Student.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.jcombat.entity;
  
public class Student {
    private String studentId;
    private String firstName;
    private String lastName;
    private Department department;
  
    public String getStudentId() {
        return studentId;
    }
  
    public void setStudentId(String studentId) {
        this.studentId = studentId;
    }
  
    public String getFirstName() {
        return firstName;
    }
  
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
  
    public String getLastName() {
        return lastName;
    }
  
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
  
    public Department getDepartment() {
        return department;
    }
  
    public void setDepartment(Department department) {
        this.department = department;
    }
  
}

Department.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.jcombat.entity;
  
import java.util.Set;
  
public class Department {
    private String depId;
    private String depName;
    private Set<Student> students;
  
    public String getDepId() {
        return depId;
    }
  
    public void setDepId(String depId) {
        this.depId = depId;
    }
  
    public String getDepName() {
        return depName;
    }
  
    public void setDepName(String depName) {
        this.depName = depName;
    }
  
    public Set<Student> getStudents() {
        return students;
    }
  
    public void setStudents(Set<Student> students) {
        this.students = students;
    }
}

5. Hibernate Utility класс

Создайте HibernateUtil.java для начальной конфигурации Hibernate, которая предоставляет нам SanceFactory isntance.

HibernateUtil.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.jcombat.utility;
  
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
  
public class HibernateUtil {
    private static final SessionFactory sessionFactory = buildSessionFactory();
      
    @SuppressWarnings("deprecation")
    private static SessionFactory buildSessionFactory() {
        try {
            return new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
  
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

6. Отображение XML в спящем режиме

Создайте файл отображения гибернации для каждого из объектов.

Student.hbm.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
<hibernate-mapping package="com.jcombat.entity">
    <class name="Student" table="student">
        <id name="studentId" column="ID">
            <generator class="native" />
        </id>
        <property name="firstName" column="FNAME" />
        <property name="lastName" column="LNAME" />
         
        <many-to-one name="department" class="com.jcombat.entity.Department" fetch="select">
            <column name="DEPT_ID" not-null="true" />
        </many-to-one>
    </class>
</hibernate-mapping>

Department.hbm.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
<hibernate-mapping package="com.jcombat.entity">
    <class name="Department" table="department">
        <id name="depId" column="DEPT_ID">
            <generator class="native" />
        </id>
        <property name="depName" column="DEP_NAME" />
        <set name="students" table="student" inverse="true" cascade="save-update" lazy="true" fetch="select">
            <key>
                <column name="DEPT_ID" not-null="true" />
            </key>
            <one-to-many class="com.jcombat.entity.Student" />
        </set>
    </class>
</hibernate-mapping>

Обратите внимание, что мы использовали Set для отображения студентов, связанных с отделом.

Ключевое слово «Каскад» часто используется в сопоставлении коллекции для автоматического управления состоянием коллекции. Таким образом, если есть набор учеников, связанных с конкретным отделом, и мы сохраняем состояние объекта Department, все связанные дочерние объекты учеников также сохраняются автоматически, тем самым экономя ручное усилие, чтобы сохранять их индивидуально. То же самое произойдет с нашим текущим примером.

7. Окончательная структура проекта

Обратитесь к приведенной ниже структуре проекта, как только мы закончим со всеми вышеуказанными шагами.

состав

7. Исполнение

Мы почти закончили. Осталось только создать клиентский класс, из которого мы будем выполнять наше приложение. Итак, давайте создадим клиентский класс MainApp.

MainApp.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.jcombat.hibernate;
  
import java.util.HashSet;
import java.util.Set;
  
import org.hibernate.Session;
import org.hibernate.SessionFactory;
  
import com.jcombat.entity.Department;
import com.jcombat.entity.Student;
import com.jcombat.utility.HibernateUtil;
  
public class MainApp {
    public static void main(String[] args) {
  
        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session session = sf.openSession();
        session.beginTransaction();
  
        Department department = new Department();
        department.setDepName("Electronics");
  
        Student student1 = new Student();
        student1.setFirstName("Abhimanyu");
        student1.setLastName("Prasad");
        student1.setDepartment(department);
  
        Student student2 = new Student();
        student2.setFirstName("Abhishek");
        student2.setLastName("Kumar");
        student2.setDepartment(department);
  
        Set<Student> studSet = new HashSet<Student>();
        studSet.add(student1);
        studSet.add(student2);
        department.setStudents(studSet);
        session.save(department);
  
        session.getTransaction().commit();
        session.close();
    }
}

Щелкните правой кнопкой мыши по классу и запустите его как «Java-приложение». Мы видим следующие записи, вошедшие в консоль IDE.

1
2
3
Hibernate: insert into department (DEP_NAME) values (?)
Hibernate: insert into student (FNAME, LNAME, DEPT_ID) values (?, ?, ?)
Hibernate: insert into student (FNAME, LNAME, DEPT_ID) values (?, ?, ?)

Проверьте отдельные таблицы в базе данных для добавленных записей.

deptable

studtable

Ссылка: Отображение XML на один из множества в Hibernate от нашего партнера JCG Абхиманью Прасада в блоге jCombat .