千山万水之Hibernate(四)——关联映射(多对一)

在上一篇文章(《千山万水之Hibernate(三)——基本映射 》)中,我们介绍了怎样通过Hibernate进行最基本的单实体映射以及Hibernate设计的一些基本原理,本篇文章将介绍关联映射中的多对一映射是如何实现的。

原理分析

我们拿学生和班级为示例,学生属于某一个班级,而且多个学生是有可能属于同一个班级的,相应的实体关系图为:
技术分享
Class的映射文件向上一篇我们介绍到的基本映射文件那样编写便可以,而对于Student实体,我们需要从Student中得出对应班级,而Student与Class正是多对一的体现,因此需要在Student中加入many-to-one标签,以表达出这种关联关系:

<?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.tgb.hibernate.Student">
        <id name="id">
            <generator class="native"></generator>
        </id>
        <property name="name" />
        <many-to-one name="classes" column="classId"></many-to-one>
    </class>
</hibernate-mapping>

操作示例

为了示例方便,首先我们编写一个简单的Hibernate操作工具类,封装SessionFactory创建、Session的打开与关闭:

public class HibernateTool {
    private static SessionFactory factory;

    static{
        try{
            Configuration cfg = new Configuration().configure();
            factory=cfg.buildSessionFactory();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public static Session getSession(){
        return factory.openSession();
    }

    public static void closeSession(Session session){
        if(session != null){
            if(session.isOpen()){
                session.close();
            }
        }
    }

    public static SessionFactory getSessionFactory(){
        return factory;
    }
}

1.调用session的Load方法,得出Student对象的级联班级对象Classes(这也是Hibernate为我们提供的一大好处):

public void testLoad(){
        Session session = null;
        try{
            session = HibernateTool.getSession();
            session.beginTransaction();

            Student student = (Student)session.load(Student.class, 2);

            System.out.println("student.name=" + student.getName());
            System.out.println("student.class.name=" + user.getClasses().getName());

            session.getTransaction().commit();
        }catch(Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally{
            HibernateTool.closeSession(session);
        }
    }

2.当保存数据时,我们已经知道关联有Transient对象的Persistent状态的对象不能直接保存至数据库,因为在清理缓存时,不能得到关联对象的标识符,因此,我们有两种解决方案,在将Student对象进行保存前,先将关联的Classes对象保存,使其保持在Persistent状态,则Student保存成功,另外一种便是设置级联保存:
技术分享
这样在保存Student对象时,也会将级联的班级对象进行保存:

public void testSave(){
        Session session = null;
        try{
            session = HibernateTool.getSession();
            session.beginTransaction();

            Class classes    = new Class();
            classes.setName("LFSFXY-TGB");

            Student student = new Student();
            student.setName("张三");
            student.setClasses(classes);
            session.save(student);

            System.out.println("student.name=" + student.getName());
            System.out.println("student.classes.name=" + student.getClasses().getName());

            session.getTransaction().commit();
        }catch(Exception e){
            e.printStackTrace();
            session.getTransaction().rollback();
        }finally{
            HibernateTool.closeSession(session);
        }
    }

总结

通过上面的介绍相信你一定知道了Hibernate中的多对一究竟是怎么一回事,通过示例我们也体会到了对象关联给我们带来的好处:级联查询出实体,舍弃了我们之前繁琐的SQL语句操作。也通过级联属性cascade简单了解了级联保存的操作。
只有通过不断的练习实践、总结才能一步步达到熟练应用的程度,继续加油!

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