woshixushigang 发表于 2013-1-26 12:49:37

hibernate 一对多one-to-many 单向 and 双向(many-to-one),inverse(反转)

hibernate 一对多 单向
classes---->student (one--->many)
类:
one
public class Classes {

private Integer id;
private String name;
private Set students;
}
many
public class Student {//不用动

private Integer id;
private String name;
}
 
hbm.xml
Classes.hbm.xml
<?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="com.model">
    <class name="Classes" table="classes" >
      <id name="id" column="id" type="java.lang.Integer">
            <generator class="native" />
      </id>
      <property name="name" column="name" type="java.lang.String" />
      <set name="students">
            <key column="class_id" />
            <one-to-many class="com.model.Student" />
      </set>
    </class>

< /hibernate-mapping>
Student.hbm.xml(不用动)
<?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="com.zd.model">
    <class name="Student" table="student" >
      <id name="id" column="id" type="java.lang.Integer">
            <generator class="native" />         
      </id>
      <property name="name" column="name" length="50" type="java.lang.String" />
    </class>

< /hibernate-mapping>
 
测试用例:
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import junit.framework.TestCase;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.model.Classes;
import com.model.Student;

public class OneToManyTest extends TestCase {

public void testSave1(){
   Session session = null;
   Transaction ta = null;
   try{
    session = HibernateUtil.getSession();
    ta = session.beginTransaction();
    Student stu1 = new Student();
    stu1.setName("z3");
    Student stu2 = new Student();
    stu2.setName("l4");
session.save(stu1); //一定要先保存,要不是瞬时对象
    session.save(stu2);
    Set stuSet = new HashSet();
    stuSet.add(stu1);
    stuSet.add(stu2);
    Classes c = new Classes();
    c.setName("Java Class");
    c.setStudents(stuSet);
session.save(c);
    ta.commit();
   }catch(Exception e){
    e.printStackTrace();
    if(ta != null){
   ta.rollback();
    }
   }finally{
    //关闭session, user变为detached离线对象
    HibernateUtil.closeSession(session);
   }

}

Hibernate: insert into student (name) values (?)
Hibernate: insert into student (name) values (?)
Hibernate: insert into classes (name) values (?)
Hibernate: update student set class_id=? where id=?
Hibernate: update student set class_id=? where id=?
注:表student 的字段class_id必须null(若为not null,就会报错)。多了2条update, 所以one-to-many保存时,不太好,不推荐。


public void testGet1(){
   Session session = null;
   Transaction ta = null;
   try{
    session = HibernateUtil.getSession();
    ta = session.beginTransaction();
    Classes c = (Classes) session.get(Classes.class, new Integer(2));
    System.out.println("Class.name=" + c.getName());
    Set stuSet = c.getStudents();
    if(stuSet != null && !stuSet.isEmpty()){
   for(Iterator it = stuSet.iterator(); it.hasNext();){
      Student s = (Student) it.next();
      System.out.println("student.name=" + s.getName());
   }
    }
    ta.commit();
   }catch(Exception e){
    e.printStackTrace();
    if(ta != null){
   ta.rollback();
    }
   }finally{
    //关闭session, user变为detached离线对象
    HibernateUtil.closeSession(session);
   }

Hibernate: select classes0_.id as id0_0_, classes0_.name as name0_0_ from classes classes0_ where classes0_.id=?
Class.name=Java Class
Hibernate: select students0_.class_id as class3_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_ from student students0_ where students0_.class_id=?
student.name=l4
student.name=z3
}
小结:one-to-may 是只配在one这端,但many另一端的表中要用外键与这相对应
<set name="students"> //name : one 中的set变量
            <key column="class_id" /> //column 表student的外键字段class_id
            <one-to-many class="com.model.Student" /> //class指many的类
      </set>

 
===============================================================
双向(many-to-one) ,在多的一端配个多对一:
修改如下:
类:
public class Student {

private Integer id;
private String name;
private Classes classes;

 
hbm.xml
Student.hbm.xml
 
<?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="com.zd.model">
    <class name="Student" table="student" >
      <id name="id" column="id" type="java.lang.Integer">
            <generator class="native" />         
      </id>
      <property name="name" column="name" length="50" type="java.lang.String" />
<many-to-one name="classes" column="class_id"></many-to-one>
    </class>

< /hibernate-mapping>
 
测试用例:
public void testSave2(){
   Session session = null;
   Transaction ta = null;
   try{
    session = HibernateUtil.getSession();
    ta = session.beginTransaction();
    Classes c = new Classes();
    c.setName("php");
    Student stu1 = new Student();
    stu1.setName("a1");
    stu1.setClasses(c);
    Student stu2 = new Student();
    stu2.setName("a2");
    stu2.setClasses(c);
session.save(c); //先保存班级
    session.save(stu1);
    session.save(stu2);
    ta.commit();
   }catch(Exception e){
    e.printStackTrace();
    if(ta != null){
   ta.rollback();
    }
   }finally{
    //关闭session, user变为detached离线对象
    HibernateUtil.closeSession(session);
   }

}
================================================
关于inverse属性:
inverse主要用在一对多和多对多双向关联上,inverse可以被设置到集合标签<set>上,
默认inverse为false,所以我们可以从”一“一端和”多“一端维护关联关系,
如果设置成inverse为true,则我们只能从多一端来维护关联关系

注意:inverse属性,只影响数据的存储,也就是持久化
<set name="students" inverse="true"> //inverse为true,则我们只能从多一端来维护关联关系
            <key column="class_id" />
            <one-to-many class="com.zd.model.Student" />
      </set>

inverse和cascade
* inverse是关联关系的控制方向
* cascade操作上的连锁反应
<div class="tit">Hibernate之中inverse与cascade的异同
页: [1]
查看完整版本: hibernate 一对多one-to-many 单向 and 双向(many-to-one),inverse(反转)