Hibernate-----一对多关联映射(映射文件方式)

一对多和多对一映射原理一致:都是在多的一端加入一个外键指向一的一端

区别在于维护的关系不同:

1、多对一维护的关系是多指向一的关系,若维护了多指向一的关系,加载多的时候就会把一加载上来

2、一对多维护的关系是一指向多的关系,若维护了一指向多的关系,加载一的时候就会把多加载上来

 

在一端维护关系存在缺陷(可用一对多双向关联映射,解决一端维护关系存在的缺陷):

1、因为多的一端Student不知道Classes的存在(也就是Student没有维护与Classes的关系);所以在保存Sudent的时候关系字段classes_id是为null的,若将该关系字段设为非空,则将无法保存数据

2、另外因为Student不维护关系,Classes维护关系,Classes就会发出多余的update语句,保证ClassesStudent有关系,这样加载Classes的时候才可以把该Classes对应的学生加载上来

 

一、单向关联映射

One(维护端:Classes)

<?xml version="1.0"encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.app.model">
    <class name="Classes" table="t_classes">
       <id name="id">
           <generator class="increment"/>
       </id>
 
       <property name="name"/>
 
       <!--  维护关系: -->
       <set name="students">
           <!-- 往多的一端加个外键 -->
           <key column="classes_id"></key>
           <one-to-many class="org.app.model.Student"/>
       </set>
    </class>
</hibernate-mapping>
To

Many(非维护端:Student)

<?xml version="1.0"encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.app.model">
    <class name="Student" table="t_student">
       <id name="id">
           <generator class="increment"/>
       </id>
       <property name="name"/>
    </class>
</hibernate-mapping>

public void testOneToMany() {
       Session session = null;
       try {
           session = HibernateUtils.getSession();
           session.beginTransaction();
 
           // 关联有方向性,一对多(一依赖多),故先有Student、再有Classes
           Student student1 = new Student();
           student1.setName("name");
           session.save(student1);
 
           Student student2 = new Student();
           student2.setName("name");
           session.save(student2);
 
           Set<Student> set = new HashSet<Student>();
           set.add(student1);
           set.add(student2);
 
           Classese classes = new Classese();
           classes.setName("className");
           classes.setStudents(set);
 
           // 最后保存维护端
           session.save(classes);
           // 先插入两条student
           // 然后插入一条classes
           // 再修改两条student(用于维护关系)
 
           session.getTransaction().commit();
       } catch (Exception e) {
           e.printStackTrace();
           session.getTransaction().rollback();
       } finally {
           HibernateUtils.closeSession(session);
       }
    }



二、双向关联映射

One(维护端:Classes)

<?xml version="1.0"encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.app.model">
    <class name="Classes" table="t_classes">
       <id name="id">
           <generator class="increment"/>
       </id>
 
       <property name="name"/>
 
       <set name="students"inverse=”true”>
         <!—加上inverse后该端不再维护关系,而是另外一端维护关系 -->
           <!-- 往多的一端加个外键 -->
           <key column="classes_id"></key>
           <one-to-many class="org.app.model.Student"/>
       </set>
    </class>
</hibernate-mapping>
To

Many(维护端:Student)

<?xml version="1.0"encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.app.model">
    <class name="Student" table="t_student">
       <id name="id">
           <generator class="increment"/>
       </id>
       <property name="name"/>
       <!--  维护关系:在多的一端加外键 -->
       <many-to-one name="classes"column="classes_id"></many-to-one>
    </class>
</hibernate-mapping>


先保存一的一端再保存多的多的一端可避免多发update语句

 

inverse属性(默认false:本端可维护关系;true:本端不维护关系,交由另一端维护)可用在一对多和多对多双向关联上

一对多关联映射通常在多的一端维护关系,让一的一端失效(设置inverse=true)

 

inverse pk cascade

inverse是控制方向上的反转,只影响存储

cascade是操作上的连锁反应(同步关联的对象)

 

 

 

 

 

 

 



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。