hibernate 关系映射
hibernate多对一映射
关联映射的本质:将关联关系映射到数据库,关联关系在对象模型域中体现为一个或多个引用
<many-to-one>标签会在“多”的一端添加一个外键,指向“一”的一端,这个外键是由<many-to-one>
中的column的属性定义的,如果忽略这个属性,默认创建的外键与实体类的属性名相同
<many-to-one>定义示例:
*<many-to-onename="group"column="groupid"/>
理解cascade
*是对象之间的连锁操作(只对增删改起作用)
hibernate一对一主键关联映射(单项关联)Person--->IdCard
主键关联映射:让两个对象的id保持相同,这样可以避免多余的字段被创建
<one-to-one>标签指示hibernate如何加载其引用对象,缺省情况下根据主键加载其引用对象
<idname="id">
<generatorclass="foreign">
<!--person中的id来源于idCard,即共享idCard主键-->
<paramname="property">idCard</param>
</generator>
</id>
<propertyname="name"/>
<!--constrained="true",当前主键上存在一个约束,表明person中的主键作为外键参照了idCard-->
<one-to-onename="idCard"constrained="true"/>
hibernate一对一主键关联映射(双项关联)Person<--->IdCard
需要在idCard加入<one-to-one>标签,指示hibernate如何加载person,默认情况下根据主键加载
<one-to-onename="person"></one-to-one>
hibernate一对一唯一外键关联映射(单项关联)Person--->IdCard
一对一唯一外键关联实际上是多对一关联映射的特例
可以采用<many-to-one>标签,指定“多”的一端unique=“true”,即限制了“多”一端的多重性为“一”
这样就构成了一对一唯一外键关联映射
personhbm
<?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.bjsxt.hibernate.Person" table="t_person"> <id name="id"> <generator class="native"> </generator> </id> <property name="name"/> <many-to-one name="idCard" unique="true"/> </class> </hibernate-mapping>
idcardhbm
<?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.bjsxt.hibernate.IdCard" table="t_idCard"> <id name="id"> <generator class="native"></generator> </id> <property name="cardNo"/> </class> </hibernate-mapping>
hibernate一对一唯一外键关联映射(双向关联)Person<--->IdCard
一对一唯一外键双向关联映射,需要在另一端(IdCard),添加<one-to-one>标签,指示hibernate如何
加载其引用对象,默认情况下根据主键加载person,因为外键关联映射中,两个实体的关系是由person的
外键IdCard维护的,所以不能指定person的主键来加载person,而是根据person的外键idCard来加载person
对象,如:
<one-to-onename="person"property-ref="idCard"></one-to-one>
hibernate一对多关联映射(单向关联)Classes--->Student
这种关联映射的原理采用的是多对一关联映射的原理
多对一关联映射,是在“多”的一端添加一个外键指向“一”的一端,它维护的关系多到一的关系
一对多关联应是,是在“一”的一端添加一个外键指向“多”的一端,它维护的关系一到多的关系
也就是说,一对多和多对一关联映射的策略是一致的,只是站的角度不同
缺点:
*更新student表中的classesid字段时,会发出多余的update语句,来维护classes到student之间的关系
*如果将t_student中的classesid设置为非空,则不能成功保存
<setname="students"order-by="id">
<!--
<keycolumn="classesid"not-null="true"></key>
-->
<keycolumn="classesid"></key>
<one-to-manyclass="com.bjsxt.hibernate.Student"/>
</set>
hibernate多对多关联映射(单项关联)user--->role
hibernate多对多关联映射(双项关联)user<--->role
基本映射
类-->数据库表
普通属性-->表字段
通过<class>映射到数据库表,通过<property>将普通属性映射到表字段。
所谓普通属性不包扩,自定义类,集合,数组
实体类主要设计原则:
*实现一个默认的(即无参数的)构造方法(constructor)
*提供一个标识属性(identifierproperty)(可选)
*使用非final的类(可选)
*为持久化字段声明访问器(accessors)(可选)
注意:类的名称和属性的名称如果和sql中的关键子重复,必须用table或column重新命名
id的映射:
了解uuid、native和assigned
注意:类的名称和类中属性的名称,如果和sql中的关键字重复,必须用table或column属性重命名
lazy策略可以用在:
*<class>标签上,可以取值:true/false
*<property>标签上,可以取值:true/false,这个特性需要类增强工具
*<set><list>等集合上,可以取值:true/false/extra
*<one-to-one>和<many-to-many>(单端关联)等标签上,可以取值:false/proxy/noproxy
概念:
1、lazy是只有需要的时候才发出sql语句
2、hibernate支持lazy策略,只有session打开状态下才有效
hibernate类级别的lazy测试,可以控制什么时候加载这些普通属性
测试session.flush
1、session在什么情况下清理缓存:
*默认情况下,当应用程序提交事务,如:Transaction.commit;
*当我们显示调用flush的时候
*在执行某些查询的时候,如:iterate
2、session.flush()主要完成两件事情:
*清理缓存
*执行sql
3、flush执行的顺序:hibernate按照save,update,delete顺序提交相关操作
flush是把cache中的数据同步到数据库中去,要清理需要调用clear()。
commit()之前默认执行flush。flush生成sql语句并执行sql语句,执行sql语句不等于事务的提交。
flush后在mysql中就可以看到插入的数据,但是mysql的隔离级别比较高,通过select语句可以查询,为可重复读。可以修改mysql的默认隔离级别为未提交对,就可以看到执行但是还没有提交的记录。