前序:
关系映射是我们Hibenrnate实体映射中比较常见的,平时用的也比较多。学习的过程我们可以想想我们以前学
习的对象关系,这里所说的关联映射其实在对象中就是引用。常用的关系映射有:
多对一关联映射
原理:
在多的一端加入一个外键,指向一的一端。同时实体中多的一端加入对一的引用。
对象和关系模型:
映射文件:
在多的一端采用如下标签映射:
<many-to-onename="group" column="groupid"/>
User.hbm.xml
<span style="font-size:18px;"><?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.wyj.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> </span>
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.wyj.hibernate.Group" table="t_group">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping
一对多关联映射
单向
原理:
一对多关联映射和多对一关联映射映射原理是一致的,都是在多的一端加入一个外键,指向一的一端。
它们的区别在于维护的关系不同:
- 多对一维护的关系是:多指向一的关系,有了此关系,在加载多的时候可以将一加载上来
- 一对多维护的关系是:一指向多的关系,有了此关系,在加载一的时候可以将多加载上来
映射文件:
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 package="com.wyj.hibernate">
<class name="Group" table="t_group">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<set name="users">
<key column="groupid"/>
<one-to-many class="User"/>
</set>
</class>
</hibernate-mapping>
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 package="com.wyj.hibernate">
<class name="User" table="t_user">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
</class>
</hibernate-mapping>
在一的一端维护关系存在缺陷:
- 因为多的一端User不知道Group的存在(也就是User没有维护与Group的关系)所以在保存User的时候关系字段groupid是为null的,如果将该关系字段设置为非空,则将无法保存数据。
- 另外因为User不维护关系,而Group维护关系,Group就会发出多余的update语句,保证Group和User有关系,这样加载Group的时候才可以把该Group对应的User加载上来。
双向
为了克服这些缺陷,我们一般将单向一对多关联映射改为双向的。
原理:
我们可以发现双向与单向的关系模型是一样的,只是在一的一端加入了多的一端的引用。采用一对多双向关
联映射的目的主要是为了解决一对多单向关联的缺陷,而不是需求驱动的。
映射文件:
一对多双向关联的映射方式:
- 在一的一端的集合上采用<key>标签,在多的一端加入一个外键。
- 在多的一端采用<many-to-one>标签。
- <key>标签和<many-to-one>标签加入的字段保持一直,否则会产生数据混乱。
Group.hbm.xml
<span style="font-size:18px;"><?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 package="com.wyj.hibernate">
<class name="Group" table="t_group">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<set name="users" inverse="true">
<key column="groupid"/>
<one-to-many class="User" />
</set>
</class>
</hibernate-mapping> </span>
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 package="com.wyj.hibernate">
<class name="User" table="t_user">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<many-to-one name="group" column="groupid"/>
</class>
</hibernate-mapping>
附:
cascade属性:
级联是对象之间的连锁操作,它只影响添加、删除和修改
inverse属性:
inverse属性可以用在一对多和多对多双向关联上,inverse属性默认为false,false表示本端可以维护关系,如
果inverse为true,则本端不能维护关系,会交给另一端维护关系,本端失效。
所以一对多关联映射我们通常在多的一端维护关系,让一的一端失效,所以设置为inverse为true。
inverse和cascade
inverse是控制方向上的反转,只影响存储
cascade是操作上的连锁反映
下篇继续一对一和多对多。