在关联关系的映射中使用得最多的就是一对多的关联,一对多的关联关系分为两种:单向一对多,双向一对多。下面分别对这两种情况进行总结:
首先准备两张表:用户表user和用户组表group
CREATE TABLE `test`.`group` (
`id` int(10) unsigned NOT NULL auto_increment,
`name` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
)
CREATE TABLE `test`.`user` (
`id` int(10) unsigned NOT NULL auto_increment,
`name` varchar(45) NOT NULL,
`group_id` int(10) unsigned default NULL,
PRIMARY KEY (`id`),
KEY `FK_users_1` (`group_id`),
CONSTRAINT `FK_users_1` FOREIGN KEY (`group_id`) REFERENCES `group` (`id`)
)
首先,来看看单向一对多的情况:
Group类中有如下属性:
private Integer id;
private String name;
private Set users = new HashSet(0);//用户的set集合,用于存一对多中的“多”的一方
User类只需要有本身的属性即可:
private Integer id;
private String name;
接下来才是重点,配置单向一对多之间的关联
Group.hbm.xml文件的配置如下:
<hibernate-mapping>
<class name="com.stream.model.Group" table="group" catalog="test">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="identity" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="45" not-null="true" />
</property>
<!-- 以下是单向一对多的配置信息-->
<set name="users" inverse="false" cascade="all">
<key>
<!-- 指定user表中引用外键的是哪一列-->
<column name="group_id"/>
</key>
<!--配置是与哪一个类之间的一对多 -->
<one-to-many class="com.stream.model.User" />
</set>
</class>
</hibernate-mapping>
在该配置文件中,inverse可以使用默认false,或者显示指定false,如以上代码。这样就指定一对多之间的关系由group这个POJO来维护。在单项一对多关联中,这一点很重要,下面我们通过测试来说明。cascade="all"指定级联的之间的等级,它具有如下几种值:
all : 所有情况下均进行关联操作。
none:所有情况下均不进行关联操作。这是默认值。
save-update:在执行save/update/saveOrUpdate时进行关联操作。
delete:在执行delete时进行关联操作。
user.hbm.xml文件的配置与User这个类一样,不需要包含如何关于关联关系的配置:
<class name="com.stream.model.User" table="user" catalog="test">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="identity" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="45" not-null="true" />
</property>
</class>
下面只举单向一对多关联保存一例来说明,其他操作类似:
Group group = new Group();
group.setName("group1");
User user1 = new User();
user1.setName("stream");
User user2 = new User();
user2.setName("fangqi");
//添加用户
group.getUsers().add(user1);
group.getUsers().add(user2);
//开启事务
Transaction transaction =session.beginTransaction();
//保存用户组
session.save(group);
//将缓冲区中的sql送到数据库中
session.flush();
//提交事务
transaction.commit();
我们没有显示的插入user1和uesr2两条记录,但是由于我们设置了cascade=all,那么在group表进行任何操作时都会关联到user表,即在保存group时,也会把user1和user2保存,这就是级联为我们带来的好处。
但是,在这里有两点需要说明的是:
1、如果在Group.hbm.xml映射文件中设置了inverse=true,那么说明这个一对多的关联关系由多的一方来维护。而在单向的一对多关联中,“多”的一方完全不知情,所以在保存往user 表中插入的两条数据,其外键group_id这一字段都是为null值。如果user表中group_id是not null的话就会出现如下异常:
org.hibernate.exception.GenericJDBCException: could not insert: [com.stream.model.User]
....
Caused by: java.sql.SQLException: Field 'group_id' doesn't have a default value。
异常信息室group_id这个字段没有设置一个默认值,其实就是我们往group_id这个非空的字段插入了一个null值。
2、如果再Group.hbm.xml映射文件中设置inverse=false,或者不设置该属性,即表示由自身来维护这个关联关系。但在保存group后,会先将user1和user2插入到数据库,并且group_id的值都为null。然后再接着两条update语句,将这两天记录的group_id字段值设置为前面插入的group的id。同样的如果user 表中group_id字段是非空的,仍然会出现上面的异常。
---------------------------------------------单向一对多的关联完毕----------------------------------------------------------
双向一对多的关联下次有时间再总结。
分享到:
相关推荐
Hibernate一对多映射
Hibernate一对多映射配置详解,很值得借鉴
hibernate的简单搭建、hibernate的一对多映射关系
这个例子会让你很快懂得hibernate一对多的映射机制,你看了以后会有很大的感触!
hibernate一对多映射源代码 希望大家可以顶一下。。
一个老师可以教多个学生 【一对多映射】 多个学生可以被一个老师教【多对一映射】 部门与员工: 一个部门有多个员工【一对多映射】 多个员工属于一个部门【多对一映射】 1.2:多对多,举例说明: 项目和开发员工:...
hibernate基于 一对多、多对一映射写的一个增加,查询,删除,修改的demo,内附数据库脚本
Hibernate一对多,多对一映射
hibernate 多对一映射 适合初学者
hibernate核心,一对多,多对多映射讲解,看了就完全搞明白了
hibernate多对一映射(XML)版
Hibernate多对一映射(注解版)
包含《多对多双向关联映射》《多对一单向关联映射》《多对一双向关联映射》《一对多单向关联映射》等文档,并有图解及例子,非常适合新手学习,尤其是刚刚接触hibernate,对映射关系不清楚的。。。。
Hibernate多对一映射实例,里面包含源程序,测试程序,映射说明
Hibernate双向一对一关联映射(注解版)
Hibernate映射一对多关联关系