首页 > 代码库 > hibernate关系映射(多对一)

hibernate关系映射(多对一)

对多一关系是最普遍也是最重要的一种对象关系,其中又包括了单向的多对一,单向的一对多以及双向的多对一关系

单向多对一

多的一方:学生(Student)

一的一方:班级(Grade)

班级类的定义以及hbm文件配置如下

1 public class Grade {2     private int id;3     private String name;4 }
 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3         "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping > 6     <class name="com.zlt.hibernatedemo.Grade" table="grade"> 7         <id name="id" column="id"> 8             <generator class="increment"></generator> 9         </id>10         11         <property name="name" column="name"></property>12     </class>13 14 </hibernate-mapping> 

 

学生类的定义以及hbm文件配置如下 

1 public class Student {2     private int id;3     private String name;4     private Grade grade;5 }
 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3         "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping > 6     <class name="com.zlt.hibernatedemo.Student" table="student"> 7         <id name="id" column="id"> 8             <generator class="increment"></generator> 9         </id>10         11         <property name="name" type="java.lang.String">  12             <column name="name" length="50" />  13         </property>14         15         <many-to-one name="grade" column="gradeid"></many-to-one>16     </class>17 18 </hibernate-mapping>

 

测试程序

 1 public class HibernateTest { 2     public static void main(String[] args) { 3         Session session = HibernateFactory.currentSession(); 4         Transaction tx = session.beginTransaction(); 5          6         Grade grade = new Grade(); 7         grade.setName("grade1"); 8          9         Student student1 = new Student();10         student1.setName("student1");11         student1.setGrade(grade);12         13         Student student2 = new Student();14         student2.setName("student2");15         student2.setGrade(grade);16         17         session.save(grade);18         session.save(student1);19         session.save(student2);20         21         tx.commit();22         session.close();23     }24 }

 

结果

 

单向一对多

多的一方:学生(Student)

一的一方:班级(Grade)

学生类的定义以及hbm文件配置如下 

1 public class Student {2     private int id;3     private String name;    4 }
 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3         "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping > 6     <class name="com.zlt.hibernatedemo.Student" table="student"> 7         <id name="id" column="id"> 8             <generator class="increment"></generator> 9         </id>10         11         <property name="name"></property>12     </class>13 14 </hibernate-mapping>

 

班级类的定义以及hbm文件配置如下 

1 public class Grade {2     private int id;3     private String name;4     private Set<Student> students = new HashSet<Student>(); 5 }
 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3         "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping > 6     <class name="com.zlt.hibernatedemo.Grade" table="grade"> 7         <id name="id" column="id"> 8             <generator class="increment"></generator> 9         </id>10         11         <property name="name" column="name"></property>12         <set name="students">13             <key column="grade_id"/>14             <one-to-many class="com.zlt.hibernatedemo.Student"/>15         </set>16     </class>17 18 </hibernate-mapping>

 

测试程序

 1 public class HibernateTest { 2     public static void main(String[] args) { 3         Session session = HibernateFactory.currentSession(); 4         Transaction tx = session.beginTransaction(); 5          6         Grade grade = new Grade(); 7         grade.setName("grade1"); 8          9         Student student1 = new Student();10         student1.setName("student1");11         12         Student student2 = new Student();13         student2.setName("student2");14         15         grade.getStudents().add(student1);16         grade.getStudents().add(student2);17         18         session.save(grade);19         session.save(student1);20         session.save(student2);21         22         tx.commit();23         session.close();24     }25

 

结果

 

 

<set>标签中可以设置cascade属性(all,save-update,delete,none)

当不设置cascade时,保存时需要执行三条语句

1 session.save(grade);2 session.save(student1);3 session.save(student2);

当设置cascade="all"后对某个grade的操作会级联到它student,所以只需执行session.save(grade)就可以同时插入三条数据到数据库

不设置cascade时,执行session.delete(grade);会把grade从数据库中删去,同时把student关联到这个grade的外键gradeid的值置为空;而设置了cascade后,删除了grade同时会把该grade对应的student对象从数据库中删去

 

<set>标签中也可以设置inverse属性(true,false)

inverse="false"(默认)生成的sql语句

Hibernate: insert into grade (name, id) values (?, ?)

Hibernate: insert into student (name, id) values (?, ?)

Hibernate: insert into student (name, id) values (?, ?)

Hibernate: update student set grade_id=? where id=?

Hibernate: update student set grade_id=? where id=?

 

inverse="true"生成的sql语句

Hibernate: insert into grade (name, id) values (?, ?)

Hibernate: insert into student (name, id) values (?, ?)

Hibernate: insert into student (name, id) values (?, ?)

同时数据库并没有关联三条数据

它意味着 grade不再作为主控方,而将关联关系的维护工作交给关联对象student来完成。在保存grade时,grade不在关心student的gradeid属性,必须由student自己去维护,即设置student.setGrade(grade); 如果需要通过student来维护关联关系,那么这个关联关系转换成双向关联。

 

双向关联

学生

1 public class Student {2     private int id;3     private String name;4     private Grade grade;5 }
 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3         "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping > 6     <class name="com.zlt.hibernatedemo.Student" table="student"> 7         <id name="id" column="id"> 8             <generator class="increment"></generator> 9         </id>10         11         <property name="name" type="java.lang.String">  12             <column name="name" length="50" />  13         </property>14         15         <many-to-one name="grade" column="gradeid"></many-to-one>16     </class>17 18 </hibernate-mapping> 

 

班级

1 public class Grade {2     private int id;3     private String name;4     private Set<Student> students = new HashSet<Student>(); 5 }
 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3         "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping > 6     <class name="com.zlt.hibernatedemo.Grade" table="grade"> 7         <id name="id" column="id"> 8             <generator class="increment"></generator> 9         </id>10         11         <property name="name" column="name"></property>12         13         <set name="students" inverse="true" cascade="all">14             <key column="gradeid"/>15             <one-to-many class="com.zlt.hibernatedemo.Student"/>16         </set>17     </class>18 19 </hibernate-mapping>

 

测试程序

public class HibernateTest {    public static void main(String[] args) {        Session session = HibernateFactory.currentSession();        Transaction tx = session.beginTransaction();                Grade grade = new Grade();        grade.setName("grade1");                Student student1 = new Student();        student1.setName("student1");                Student student2 = new Student();        student2.setName("student2");                //只需要session.save(grade);就能插入三条数据,需要先设置cascade        grade.getStudents().add(student1);        grade.getStudents().add(student2);                //因为grade中inverse设置为ture,所以需要由student维护关联关系,设置graidid        student1.setGrade(grade);        student2.setGrade(grade);                session.save(grade);        tx.commit();        session.close();            }}

 

结果:

产生3条sql语句(如果用一的那端维护关联关系,会产生5条sql,所以在多的一方设置inverse="true",有助于性能的改善)

Hibernate: insert into grade (name, id) values (?, ?)

Hibernate: insert into student (name, gradeid, id) values (?, ?, ?)

Hibernate: insert into student (name, gradeid, id) values (?, ?, ?)

 

自身一对多配置

 1 <?xml version="1.0" encoding="utf-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 3      4     <hibernate-mapping> 5         <class name="Category" table="category"> 6             <id name="id" type="string"> 7                 <column name="id"></column> 8                 <generator class="uuid"></generator> 9             </id>10             11             <property name="name" column="name" type="string"></property>12             13             <set name="chidrenCategories" cascade="all" inverse="true">14                 <key column="category_id"></key>15                 <one-to-many class=" Category"/>16             </set>17             18             <many-to-one name="parentCategory"  column="category_id"></many-to-one>19             20         </class>21     </hibernate-mapping>