- One to One 映射关系(只有当映射自定义对象时,才会用,hibernate支持的java类型都可直接设成属性,了解第一和第二种的xml即可)
- 基于外键的单向一对一 (xml和annotation都实现了)
- 基于外键的双向一对一(xml和annotation都实现了)
- 基于主键的单向一对一(xml实现了)
- 基于主键的双向一对一 (未实现)
注: Project中使用XML/Annotation时应统一
一、基于外键的单向一对一
例子:一本书只有一个主人,能通过书查找修改人的信息,不能通过人查找修改书的信息
类属性变化:Book类中要添加user类的对象,并提供get和set方法,User类无需修改属性
- XML:
Book类
<hibernate-mapping>
<class name="test.Book" table="hbn_book" >
<!--name属性名,class类的位置,column外键列的名称,unique限定为唯一-->
<many-to-one name="user" class="test.User" column="uid" unique="true" />
</class>
</hibernate-mapping>
- Annotation:
Book类
@OneToOne()
@JoinColumn(name="uid",unique=true)//unique限定是关键
private User user;
二、基于外键的双向一对一
例子:一本书只有一个主人,能通过书查找修改人的信息,也能通过人查找修改书的信息
类属性变化:Book类中要添加user类的对象,User类要添加book类的对象,并提供get和set方法
- XML:
Book类
<hibernate-mapping>
<class name="test.Book" table="hbn_book" >
<!--name属性名,class类的位置,column外键列的名称,unique限定为唯一-->
<many-to-one name="user" class="test.User" column="uid" unique="true" />
</class>
</hibernate-mapping>
User类
<hibernate-mapping>
<class name="test.User" table="hbn_user" >
<!--name属性名,property-ref关联many-to-one中的name属性,它的名字一样-->
<one-to-one name="book" property-ref="user"></one-to-one>
</class>
</hibernate-mapping>
- Annotation:
Book类
@OneToOne(mappedBy="book")//被下面User类中的book属性关联
private User user;
User类
@OneToOne
@JoinColumn(name="bid",unique=true)//外键列名
private Book book;
三、基于主键的单向一对一
例子:一本书只有一个主人,能通过书查找修改人的信息,不能通过人查找修改书的信息
类属性变化:Book类中要添加user类的对象,并提供get和set方法,User类无需修改属性
- XML:
Book类
<hibernate-mapping>
<id name="id"><!--此处的foreign生成策略,会取得关联对象的标识,property标签内是关联对象-->
<generator class="foreign">
<param name="property">user</param>
</generator>
</id>
<class name="test.Book" table="hbn_book" >
<!--one-to-one标签指示hibernate如何加载其关联对象,默认根据主键加载也就是拿到关系字段值,
根据对端的主键来加载关联对象。constrained="true"表示当前Book的主键id还是一个外键,
参照了对应端的主键user的id主键,会生成外键约束语句。-->
<one-to-one name="user" constrained="true" />
</class>
</hibernate-mapping>
注:采用foreign映射策略在保存book对象的同时也会保存关联的对象,也就是user,他们之间还有级联关系。但是反之就不可以,也就是说,如果只保存user对象,是会出错的,不会保存book对象,因为关系的维护端在book端,user根本就不知道book的存在。主键关联映射有弊端,不好维护。
- Annotation: 未知
Book类
四、基于主键的双向一对一
例子:一本书只有一个主人,一个人只有一本书,能通过书查找修改人的信息,也能通过人查找修改书的信息
类属性变化:Book类中要添加user类的对象,User类要添加book类的对象,并提供get和set方法
- XML:
Book类
<hibernate-mapping>
<class name="test.Book" table="hbn_book" >
<one-to-one name="user" constrained="true" cascade="save-update" />
<!--constrained(约束) 表明该类对应的数据库表,和被关联的对象所对应的数据库表之间,
通过一个外键引用对主键进行约束。这个选项影响save() 和delete() 在级联执行时的先后顺序-->
</class>
</hibernate-mapping>
User类
<hibernate-mapping>
<class name="test.User" table="hbn_user" >
<one-to-one name="book" constrained="true" cascade="save-update" />
</class>
</hibernate-mapping>
- Annotation: 未知
Book类
注:
1、在没有设置级联时,映射之间有依赖,需要注意保存的先后
2、单向时把没映射的对象,对应的get和set方法都删了
3、主键如果使用自增,注意session.save的顺序会影响id的顺序,并且不要用uuid
4、如果关系通过中间表维护,修改关系,只会删除中间表的记录
5、在session关闭前出现了异常,缓存建议清空一次,session可能残留对象
6、从多的一方维护获取信息,sql语句会少,效率会高