知道了多对1关联映照的映照原理,我们再来看1对1关联的情况,1对1分映照有两种实现方案:
对其中关联的情况我们又各分为单向、双向两种,而对1对1,Hibernate采取one-to-one标签进行标识。
我们拿人(Person)与身份证件(IdCard)为1对1关联对象的示例,他们的实体关系图为:
采取第1种方案,则Person对应数据库表与IdCard对应数据库表中的主键是逐一对应的,不需要添加过剩的字段来表示外键。Person关联映照文件中的配置为:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping⑶.0.dtd">
<hibernate-mapping>
<class name="com.tgb.hibernate.Person" table="t_person">
<id name="id">
<!-- 主键策略foreign -->
<generator class="foreign">
<!-- property指关联对象 -->
<param name="property">idCard</param>
</generator>
</id>
<property name="name" />
<one-to-one name="idCard" constrained="true" />
</class>
</hibernate-mapping>
注:one-to-one标签中的 constrained=”true”表示当前主键同时也是1个外键,参照IdCard中的主键。
1.调用session的Load方法,得出Person对象的级联班级对象IdCard
public void testLoad(){
Session session = null;
Transaction tx = null;
try{
session = HibernateUtils.getSession();
tx = session.beginTransaction();
Person person = (Person)session.load(Person.class, 1);
System.out.println("person.name = " + person.getName());
System.out.println("person.idCard.cardNo = " + person.getIdCard().getCardNo());
session.save(person);
tx.commit();
}catch(Exception e){
e.printStackTrace();
if(tx != null){
tx.rollback();
}
}finally{
HibernateUtils.closeSession(session);
}
}
与上篇文章介绍的类似,通过one-to-one标签的作用,我们查询Person对象的同时,级联查询除IdCard对象
2.默许级联保存Idcard机制
public void testSave(){
Session session = null;
Transaction tx = null;
try{
session = HibernateUtils.getSession();
tx = session.beginTransaction();
IdCard idCard = new IdCard();
idCard.setCardNo("11111111111");
Person person = new Person();
person.setName("张3");
person.setIdCard(idCard);
session.save(person);
tx.commit();
}catch(Exception e){
e.printStackTrace();
if(tx != null){
tx.rollback();
}
}finally{
HibernateUtils.closeSession(session);
}
}
上篇文章中我们提到过,在援用有Transient对象的Persistent状态的对象进行保存时,会出现异常,但在1对1主键关联映照上不会出现此种情况。也就是说,1对1默许带有cascade属性。对1对1主键关联映照,双向关联的配置即是在IdCard端加入one-to-one标签便可,此标签仅影响加载,不影响存储。
综合来看将来如果改成多对1则不可修改,灵活性较差、扩大性不好。
我们可将1对1的情况看做是多对1情况的1种极端体现,我们可以采取many-to-one标签配合unique属性来给其相对应的表上添加外键字段,这类方式可解决使用主键关联映照的弊端。相干映照文件以下:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping⑶.0.dtd">
<hibernate-mapping>
<class name="com.tgb.hibernate.Person" table="t_person">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<many-to-one name="idCard" unique="true"></many-to-one>
</class>
</hibernate-mapping>
有关相应的操作,可参照前1篇文章的多对1下示例。
我们可以看到1对1主键关联到1对1外键关联的转变可以看做是另外一种角度下看待问题,通过这样的思想,1些本来要求刻薄的情况我们一样可以通过另外一种方式来处理,到达相同的效果,并且实现将来变更的灵活应对。