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