SSH之hibernate—1和n的关联映射

来源:互联网 发布:业余足球平台软件 编辑:程序博客网 时间:2024/04/30 10:57

      关联映射将关联关系映射到数据库中,所谓的关联关系在对象模型中就是一个或多个引用。那么hibernate在加载的时候根据关系自动加载对象,不用再分步查询。这里介绍一对多和多对一的关联映射。

一、n:1

1、对象模型


      关联是有方向的,只能从user看到group,反过来看不到,根据uml知识,这里的use中持有group的引用,也就是外键

2、映射文件

group:

<hibernate-mapping><class name="com.zx.hibernate.Group" table="t_group"><id name="id"><generator class="native" /></id><property name="name" /></class></hibernate-mapping>
  group的映射文件非常简单,因为它没持有引用,只是简单的属性

user:

 

<hibernate-mapping><class name="com.zx.hibernate.User" table="t_user" lazy="false"><id name="id"><generator class="native" /></id><property name="name" /><span style="color:#FF0000;"><many-to-one name="group" column="groupid" /></span></class></hibernate-mapping>
      name是group在user中的成员变量名,因为group是关键字,所以要重命名

3、好处

         这种关联的好处体现在查询上,按照以前的查询方式,首先从数据库中查出关联的外键值,然后再从另一张表中查,这种分步查找浪费时间和精力。而添加关联后,hibernate加载user对象同时加载group的数据,提高查询效率。

代码示例:

public void testLoad1(){Session session = null;try{session = hibernateUtils.getSession();session.beginTransaction();User user =(User)session.load(User.class, 1);System.out.println("user.name" + user.getName());System.out.println("user.group.name" + user.getGroup().getName());session.getTransaction().commit();        }catch(Exception e){e.printStackTrace();session.getTransaction().rollback();}finally{hibernateUtils.closeSession(session);}}

    代码中根据id值查找user对象,同时加载了group对象。


二、1:n

    它们其实是一个关系,只是从不同的角度看,映射文件的写法不同

1、对象模型

     

        

2、映射文件

student: 

<hibernate-mapping><class name="com.zx.hibernate.Student" table="t_student" ><id name="id"><generator class="native" /></id><property name="name" /></class></hibernate-mapping>
classes:

<hibernate-mapping><class name="com.zx.hibernate.Classes" table="t_classes"><id name="id"><generator class="native" /></id><property name="name" /><set name="students"><key column="classeid" /><one-to-many class="com.zx.hibernate.Student"/></set></class></hibernate-mapping>
          <key>表示为多的一端加字段,一的一端维护关系,这样在生成表之后在student的表中会多一个classesid的字段,其实也是外键

3、作用:查询组的时候直接把组中的学生查出来

 

public void testLoad1(){Session session = null;try{session = hibernateUtils.getSession();session.beginTransaction();Classes classes = (Classes)session.load(Classes.class, 1);System.out.println("classes.name=" + classes.getName());Set students = classes.getStudents();for(Iterator iter = students.iterator();iter.hasNext();){Student student = (Student)iter.next();System.out.println("student.name="  + student.getName());}session.getTransaction().commit();}catch(Exception e){e.printStackTrace();session.getTransaction().rollback();}finally{hibernateUtils.closeSession(session);}}

      因为classes和students有关联映射的关系,所以在加载classes的时候会加载学生

4、缺陷

     * 因为多的一端的student不知道classes的存在(也就是student没有维护与classes的关系)所以在保存student的时候关系字段classes是为null的,如果将该关系字段设置为空,则 无法保存数据
     *另外因为student不维护关系,而classes维护关系,classes就会发出多余的update

5、解决办法

     为了避免问题出现,一般设为双向关联,让多的一端也维护关系

三、总结

 1、关联映射原理:在多的一端加入一个外键指向一的一端,只是角度不同

 2、区别:

        *多对一:多指向一的关系,加载多的时候会把一加上

        *一对多:一指向多,加载一的时候会把多加上


     3、加载关联对象不用再发语句,hibernate自动加载               

0 0