一对一主键关联映射:我们来拿人和身份证举例。采用一对一主键关联映射,他要表达的意思是人的 id 来自于身份证的 id 。要想在人的表中存数据,在身份证表中必须有对应的 id 的身份证记录。如图所示:
表关系为:
我们看一下具体的实现:
实体类实现:
public class Person {
private int id ;
private String name ;
private IdCard idCard ; // 提供关联的属性 …. 省略 get , set 方法 } |
public class IdCard {
private int id ;
private String cardNo ; …. 省略 get , set 方法 }
|
对应的映射文件设置为:
Person.hbm.xml < hibernate-mapping > < class name = "com.bjpowernode.hibernate.Person" table = "t_person" > < id name = "id" > <!-- 采用 foreign 生成策略, forgeign 会取得关联对象的标识,通俗点说就是 person 中这个主键 id 来自于 idCard 对象的主键。而从实体属性中可以知道 idCard 为 IdCard 类型,即 Person 中主键来自于 IdCard 中的主键 --> < generator class = "foreign" > <!-- property 只关联对象 --> < param name = "property" > idCard </ param > </ generator > </ id > < property name = "name" /> <!-- one-to-one 指示 hibernate 如何加载其关联对象,默认根据主键加载 也就是拿到关系字段值,根据对端的主键来加载关联对象 constrained="true 表示,当前主键 (person 的主键 ) 还是一个外键 参照了对端的主键( IdCard 的主键),也就是会生成外键约束语句 --> < one-to-one name = "idCard" constrained = "true" /> </ class > </ hibernate-mapping > |
IdCard.hbm.xml < hibernate-mapping > < class name = "com.bjpowernode.hibernate.IdCard" table = "t_idCard" > < id name = "id" > < generator class = "native" /> </ id > < property name = "cardNo" /> </ class > </ hibernate-mapping >
|
采用一对一主键关联映射,两个实体的主键一样,这样就不需要加入多余的字段了。我们在加载维护关系的一端如例子中提到的 Person 时,从他的实体类实现也可以看出,要给他的 IdCard 属性赋值。但是赋值时,是不需要必须显示的用 session 的 save 将其变为 Persistent 状态的。因为一对一的主键关联映射已经为我们执行了此操作。也可以说他默认了 cascade 级联特性。说了一对一主键关联映射,自然也少不了双向关联映射。一对一主键双向关联映射和单向关联映射在存储方式上是没有什么不同的。但在查询上会稍有不同。看一下实现:
实体实现:
public class IdCard {
private int id ;
private String cardNo ;
private Person person ; // 关联 Person 对象 … 省略 get , set 方法 }
|
public class Person {
private int id ;
private String name ;
private IdCard idCard ; // 关联 IdCard 对象 … 省略 get , set 方法 }
|
从实体类上来说,每端都能看到另一端的对象。查询的时候,我们自然可以从任意一段进行查询了。这是一点不同。再来看映射文件
IdCard.hbm.xml < hibernate-mapping > < class name = "com.bjpowernode.hibernate.IdCard" table = "t_idCard" > < id name = "id" > < generator class = "native" /> </ id > < property name = "cardNo" /> <!-- 相对于单向,只是多了一句 one-to-one --> < one-to-one name = "person" /> </ class > </ hibernate-mapping >
|
Person.hbm.xml < hibernate-mapping > < class name = "com.bjpowernode.hibernate.Person" table = "t_person" > < id name = "id" > < generator class = "foreign" > <!-- property 只关联对象 --> < param name = "property" > idCard </ param > </ generator > </ id > < property name = "name" /> < one-to-one name = "idCard" constrained = "true" /> </ class > </ hibernate-mapping > |
可以看出 Person 的映射文件与单向关联是完全一样的。在单向关联中,我们只能从 Person 一端查询的时候才可以查询到 IdCard 端的值。如果我们只查询 IdCard 的属性, Person 是不能被查询到的。而在双向关联中,我们则可以通过任意一端查询到另外一端的属性。单项和双项在这一区别上得到了验证。
一对一唯一外键关联映射请看下一篇博客。