Hibernate对象关系映射----关联映射(一)
关系映射之间的关系是讲对象之间的关系,并不指数据库表的关系(外键关系),下面逐一分析解释。
多对一关联映射(User---->Group)
原理:在多的一端加入一个外键,指向一的一端。
举例:多个用户(User)属于某个用户组(Group)。
User对象的映射文件User.hbm.xml。
[html]
<hibernate-mapping>
<class name="com.snail.hibernate.User" table="t_user">
<id name="id" column="user_id">
<generator class="native"/>
</id>
<property name="name" length="30" unique="true" not-null="true"/>
<many-to-one name="group" column="groupid" cascade="save-update"/>
</class>
</hibernate-mapping>
这是最常用的映射关系,在对象模型中是User对象持有Group对象的一个引用,在具体配置中, 多的一端(User)用<many-to-one>标签加入关联对象(Group)的主键(groupid)。cascade(级联)意思是指定两个对象之间的操作联动关系,对一个对象执行了操作后,对其指定的级联对象也需要执行相同的操作。如果不设置上面cascade的save-update属性,那么必须在每个瞬时对象后显示调用save或update方法,否则将抛出org.hibernate.TransientObjectException异常。
一对多关联映射(单向Classes---->Student)
原理:一对多关联映射和多对一关联映射原理一致,不同在于:多对一维护的关系是在加载多的一端时可以将一加载上来;一对多可以在加载一时将多加载上来。
举例:某个班级(Classes)有多位学生(Student)。
一的一端Classes的映射文件Classes.hbm.xml。
[html] view plaincopy
<hibernate-mapping package="com.snail.hibernate">
<class name="Classes" table="t_classes">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="students">
<key column="classesid"/>
<one-to-many class="Student"/>
</set>
</class>
</hibernate-mapping>
在对象模型中,一的一端(Classes)以集合Set的方式持有Student的引用(private Set students),在具体配置中,<set> 元素用来映射Set类型的属性,除了<set>,还有<list>, <map>, <bag>, <array> 和 <primitive-array> 映射元素,写完<set>元素后,必须指明里面放什么内容,在一的一端使用<key>标签,在多的一端加入一个外键,将两个对象建立连接。<one-to-many>指明set内放入的是Student对象。
在一的一端维护关系存在缺陷:
* 因为多的一端Student不知道Classes的存在(也就是Student没有维护与Classes的关系),所以在保存Student的时候关系字段classesid是为null的,如果将该关系字段设置为非空,则将无法保存数据。
* 另外因为Student不维护关系,而Classes维护关系,Classes就会发出多余的update语句,保证Classes和Student有关系,这样加载Classes的时候才可以把该Classes对应的学生加载上来。
一对多关联映射(双向Classes<---->Student)
原理:采用一对多双向关联映射的目的主要是为了主要是为了解决一对多单向关联的缺陷,而不是需求驱动的。
举例:同上例。
一的一端Classes映射文件Classes.hbm.xml。
[html]
<hibernate-mapping package="com.snail.hibernate">
<class name="Classes" table="t_classes">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="students" inverse="true">
<key column="classesid"/>
<one-to-many class="Student"/>
</set>
</class>
</hibernate-mapping>
多的一端Student的映射文件Student.hbm.xml。
[html] view plaincopy
<hibernate-mapping package="com.snail.hibernate">
<class name="Student" table="t_student">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="classes" column="classesid"/>
</class>
</hibernate-mapping>
这两个配置文件和上面介绍的映射关系相同,不多做介绍。值得注意的是Classes.hbm.xml中inverse属性,inverse属性可以用在一对多和多对多双向关联上,inverse属性默认为false,为false表示本端可以维护关系,如果inverse为true,则本端不能维护关系,会交给另一端维护关系,本端失效,所以一对多关联映射我们通常在多的一端维护关系,让一的一端失效,所以设置为inverse为true。
inverse和cascade的区别
* inverse是控制方向上的反转,只影响存储
* cascade是操作上的连锁反映
补充:软件开发 , Java ,