程序员人生 网站导航

千山万水之Hibernate(五)――关联映射(一对一)

栏目:综合技术时间:2015-05-22 08:46:22

知道了多对1关联映照的映照原理,我们再来看1对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的情况看做是多对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些本来要求刻薄的情况我们一样可以通过另外一种方式来处理,到达相同的效果,并且实现将来变更的灵活应对。

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐