Hibernate 关联映射
identity 是mysql主键的生成方式,sequence是oracle的.所以配置时要注意底层的数据库.identity的生成策略要求字段是数字型的,比如long,或者int等.
一对多的关联映射必须在其中的一端持有另外一端的引用.并且通过映射配置实现.多对一的关联映射,左边是多的关系.比如多个学生属于一个班级,那么多的一端就是学生.其实,一对多和多对一只是考虑的角度不一致.实际上没有本质的区别.
在多的一端加上映射标签
<many-to-one name="" column>
和properties并列出现.这个字段在导出表时会在多的一端加上该字段,并且作为外键参照一的一端的主键.
实际存储数据初始化对象时需要先初始化一的一端数据,即班级数据.当然,如果在多对一的映射标签里加上cascade属性,值设为all的话会在(删除修改保存)时级联保存相关的数据.删除操作时需要注意,因为不能因为删除了一个学生,就将班级删除.级联的含义是对象的连锁操作.
加载数据(load或者get时)可以不配置级联关系.因为多对一的关联映射标签已经维持了这种关系.
持久对象不能引用瞬时对象.所以必须先save班级数据.
数据库本身的生成策略需要访问额外的表,需要加锁,并发性不怎么好.
实体类的设计原则:
需要一个无参数的构造方法
提供标识(可选)
使用非final,因为代理类的实现需要使用继承.
为持久化字段声明访问器每次导出时表都被删除,然后重新创建.如果需要表字段发生变化时才重新创建,需要在hibernate.cfg.xml文件里配置属性hibernate.hbm2dll.auto的值为update.
更改后以前的字段保留,存取数据时该字段为空.
一对一单双向映射.单向,访问时单方向的,双向式彼此都能互相访问.主键关联,是一个对象的主键以外键的形式参照另一方的主键.
一对一的生成策略不再是uuid或者native,应该是foreign,同时应继续加入一个子标签<param name="propertites">属性值</param>
<one-to-one constrain="trued">默认根据主键加载.不会像多对一一样在多的一端的映射表里加入了字段.默认了cascade的属性.
hibernate一对一主键关联映射(单向关联Person---->IdCard)
一对一主键关联映射:让两个实体对象的id保持相同,这样可以避免多余的字段被创建
具体映射:
<id name="id">
<!--person的主键来源idCard,也就是共享idCard的主键-->
<generatorclass="foreign">
<paramname="property">idCard</param>
</generator>
</id>
<propertyname="name"/>
<!--one-to-one标签的含义,指示hibernate怎么加载它的关联对象,默认根据主键加载,
constrained="true",表明当前主键上存在一个约束,person的主键作为外键参照了idCard
-->
<one-to-one name="idCard" constrained="true"/>唯一外键关联时需要在一端多加入一个字段.他是多对一的一个特例,只需在多的一端的多余字段的唯一性设置为true就可以.
hibernate一对一唯一外键关联映射(单向关联Person---->IdCard)
一对唯一外键关联映射是多对一关联映射的特例
可以采用<many-to-one>标签,指定多的一端的unique=true,这样就限制了多的一端的多重性为一通过这种手段映射一对一唯一外键关联
hibernate一对一唯一外键关联映射(双向关联Person<---->IdCard)
一对一唯一外键关联双向,需要在另一端(idcard),添加<one-to-one>标签,指示hibernate如何加载
其关联对象,默认根据主键加载person,外键关联映射中,因为两个实体采用的是person的外键维护的关系,
所以不能指定主键加载person,而要根据person的外键加载,所以采用如下映射方式:
<one-to-onename="person"property-ref="idCard"/>