В этом примере вы узнаете, как отображать отношения один-ко-многим, используя Hibernate. Рассмотрим следующие отношения между Студентом и Телом .
В зависимости от отношений студент может иметь любое количество телефонных номеров.
Для того, чтобы создать эти отношения вам нужно иметь СТУДЕНТ , PHONE и STUDENT_PHONE таблицы. Реляционная модель показана ниже.
Для создания таблицы STUDENT и PHONE необходимо создать следующие файлы отображения гибернации.
Student.hbm.xml используется для создания СТУДЕНТА и STUDENT_PHONE таблицы.
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.vaannila.student.Student" table="STUDENT"> <meta attribute="class-description">This class contains student details.</meta> <id name="studentId" type="long" column="STUDENT_ID"> <generator class="native" /> </id> <property name="studentName" type="string" not-null="true" length="100" column="STUDENT_NAME" /> <set name="studentPhoneNumbers" table="STUDENT_PHONE" cascade="all"> <key column="STUDENT_ID" /> <many-to-many column="PHONE_ID" unique="true" class="com.vaannila.student.Phone" /> </set> </class> </hibernate-mapping>
Мы используем элемент « многие ко многим», чтобы создать отношения «один ко многим» между сущностями « Студент» и « Телефон» . Поскольку у студента может быть любое количество телефонных номеров, мы используем коллекцию для хранения значений. В этом случае мы используем Set. Элемент « многие ко многим» обычно используется для создания отношения «многие ко многим», здесь мы помещаем уникальное ограничение в столбец « PHONE_ID» , что делает отношение «один ко многим».
Phone.hbm.xml используется для создания таблицы PHONE .
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.vaannila.student.Phone" table="PHONE"> <meta attribute="class-description">This class contains student's phone number details.</meta> <id name="phoneId" type="long" column="PHONE_ID"> <generator class="native" /> </id> <property name="phoneType" type="string" length="10" column="PHONE_TYPE" /> <property name="phoneNumber" type="string" length="15" column="PHONE_NUMBER" /> </class> </hibernate-mapping>
Теперь создайте файл конфигурации Hibernate и добавьте все файлы сопоставления.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver </property> <property name="hibernate.connection.url">jdbc:hsqldb:hsql://localhost </property> <property name="hibernate.connection.username">sa</property> <property name="connection.password"></property> <property name="connection.pool_size">1</property> <property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect </property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">create-drop</property> <mapping resource="com/vaannila/student/Student.hbm.xml"/> <mapping resource="com/vaannila/student/Phone.hbm.xml"/> </session-factory> </hibernate-configuration>
После создания файла конфигурации сгенерируйте файлы классов Java с помощью Hibernate Tools. (Чтобы сгенерировать код с помощью Hibernate Tools, см. Этот пример )
Будут созданы следующие классы.
package com.vaannila.student; // Generated Sep 3, 2009 8:47:06 PM by Hibernate Tools 3.2.4.GA import java.util.HashSet; import java.util.Set; /** * This class contains student details. */ public class Student implements java.io.Serializable { private long studentId; private String studentName; private Set<Phone> studentPhoneNumbers = new HashSet<Phone>(0); public Student() { } public Student(String studentName) { this.studentName = studentName; } public Student(String studentName, Set<Phone> studentPhoneNumbers) { this.studentName = studentName; this.studentPhoneNumbers = studentPhoneNumbers; } public long getStudentId() { return this.studentId; } public void setStudentId(long studentId) { this.studentId = studentId; } public String getStudentName() { return this.studentName; } public void setStudentName(String studentName) { this.studentName = studentName; } public Set<Phone> getStudentPhoneNumbers() { return this.studentPhoneNumbers; } public void setStudentPhoneNumbers(Set<Phone> studentPhoneNumbers) { this.studentPhoneNumbers = studentPhoneNumbers; } }
package com.vaannila.student; // Generated Sep 3, 2009 8:47:06 PM by Hibernate Tools 3.2.4.GA /** * This class contains student's phone number * details. */ public class Phone implements java.io.Serializable { private long phoneId; private String phoneType; private String phoneNumber; public Phone() { } public Phone(String phoneType, String phoneNumber) { this.phoneType = phoneType; this.phoneNumber = phoneNumber; } public long getPhoneId() { return this.phoneId; } public void setPhoneId(long phoneId) { this.phoneId = phoneId; } public String getPhoneType() { return this.phoneType; } public void setPhoneType(String phoneType) { this.phoneType = phoneType; } public String getPhoneNumber() { return this.phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } }
package com.vaannila.student; import java.util.HashSet; import java.util.Set; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Transaction; import com.vaannila.util.HibernateUtil; public class Main { public static void main(String[] args) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); Set<Phone> phoneNumbers = new HashSet<Phone>(); phoneNumbers.add(new Phone("house","32354353")); phoneNumbers.add(new Phone("mobile","9889343423")); Student student = new Student("Eswar", phoneNumbers); session.save(student); transaction.commit(); } catch (HibernateException e) { transaction.rollback(); e.printStackTrace(); } finally { session.close(); } } }
Создайте класс Main для запуска примера.
package com.vaannila.student; import java.util.HashSet; import java.util.Set; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Transaction; import com.vaannila.util.HibernateUtil; public class Main { public static void main(String[] args) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); Set<Phone> phoneNumbers = new HashSet<Phone>(); phoneNumbers.add(new Phone("house","32354353")); phoneNumbers.add(new Phone("mobile","9889343423")); Student student = new Student("Eswar", phoneNumbers); session.save(student); transaction.commit(); } catch (HibernateException e) { transaction.rollback(); e.printStackTrace(); } finally { session.close(); } } }
При выполнении класса Main вы увидите следующий вывод.
Таблица STUDENT имеет одну запись.
Таблица PHONE имеет две записи.
Таблица STUDENT_PHONE содержит две записи, которые связывают номера студентов и студентов.
Одна запись студента указывает на два телефонных номера, это иллюстрирует сопоставление «один ко многим».
Структура папок примера показана ниже.
Вы можете скачать исходный код этого примера здесь.