【HIbernate】(五)关联映射之多对一映射


      上篇博客中介绍了hibernate的基本映射,下面跟小编接着来学习Hibernate的关联映射吧。

关联映射,就是将关联关系映射到数据库中。所谓的关联关系就是在对象模型中就是一个或多个引用。在对象模型中,关联是有方向的。所以关系映射有四种:多对一、一对一、一对多、多对多。

【多对一】

1、需求:

      User-Group多个用户属于某个组。例如当前有个项目需要几个人进行敏捷开发,于是需要从员工中挑几个人形成新的小组进行开发,待到项目完成之后小组自行解散。这是,User表和Group表就是多对一的关系,并且是聚合关系,由User指向Group,也就是说从用户可以看到Group,而从组看不到用户。

2、映射原理:

      在多的一端加入一个外键,指向一的一端.在多的一端采用如下标签映射:

<many-to-one name=”外键实体 column=”外键名称/>

下面来看一个小例子吧。项目结构如下图:


Group实体类(Group.Java):

package com.bjpowernode.hibernate;

public class Group {

    private int id;

    private String name;

    // get和set略
}

Group映射文件(Group.hbm.xml):

<?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.bjpowernode.hibernate.Group" table="t_group">
        <id name="id">
            <generator class="native" />
        </id>
        <property name="name" />
    </class>
</hibernate-mapping>

User实体类(User.java):

package com.bjpowernode.hibernate;

public class User {

    private int id;

    private String name;

    private Group group;

    // get和set略
}

User映射文件(User.hbm.xml):

<?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.bjpowernode.hibernate.User" table="t_user">
        <id name="id">
            <generator class="native" />
        </id>
        <property name="name" />
        <many-to-one name="group" column="groupid" />
    </class>
</hibernate-mapping>

⑤其他的代码略(前面博客中有介绍)

建表结果如下图:


下面来添加一条数据试试。

测试方法如下:

public void testSave1() {
    Session session = null;
    try {
        session = HibernateUtils.getSession();
        session.beginTransaction();

        Group group = new Group();
        group.setName("一班");

        User user1 = new User();
        user1.setName("张三");
        user1.setGroup(group);

        User user2 = new User();
        user2.setName("李四");
        user2.setGroup(group);

        session.save(user1);
        session.save(user2);
        session.getTransaction().commit();
    } catch (Exception e) {
        e.printStackTrace();
        session.getTransaction().rollback();
    } finally {
        HibernateUtils.closeSession(session);
    }
}

       但是结果却出错了,在清理缓存时会发生错误TransientObjectException,因为Group为Transient状态,没有被session,在数据库中没有匹配的数据,而User为Persistent状态,在清理缓存时hibernate在缓存中无法找到Group对象,结论是Persistent状态的对象不能引用Transient状态的对象

       解决方法有二:第一,在保存User之前先执行保存外键实体Group;第二,在配置文件中添加级联属性配置,级联是对象之间的连锁操作,它只影响添加、删除和修改。具体实现如下:

第一种:

public void testSave2() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();

            Group group = new Group();
            group.setName("一班");
            session.save(group);

            User user1 = new User();
            user1.setName("张三");
            user1.setGroup(group);

            User user2 = new User();
            user2.setName("李四");
            user2.setGroup(group);

            session.save(user1);
            session.save(user2);
            // 可以正确的保存数据
            // 因为Group和User都是Persistent状态的对象
            // 所以在hibernate清理缓存时在session中可以找到关联对象
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        } finally {
            HibernateUtils.closeSession(session);
        }
    }

第二种:

<?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.bjpowernode.hibernate.User" table="t_user">
        <id name="id">
            <generator class="native" />
        </id>
        <property name="name" />
        <many-to-one name="group" column="groupid" cascade="save-update" />
    </class>
</hibernate-mapping>

【补充:级联】

级联属性cascade:是指定两个对象之间的操作联动关系,对一个对象执行了操作之后,对其指定的级联对象也需要执行相同的操作。有以下四种取值:

all:代表在所有的情况下都执行级联操作。

none:在所有情况下都不执行级联操作。

save-update:在保存和更新的时候执行级联操作。

delete:在删除的时候执行级联操作。

原文地址:http://blog.csdn.net/u013036274/article/details/64128035

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值