Hibernate 一对一主键双向关联

来源:互联网 发布:天津seo点击工具 编辑:程序博客网 时间:2024/05/17 22:53

一对一主键关联

一对一主键关联是指两个表共享一个主键值且一个的主键同时还是这个表的外键
这里写图片描述

E-R图(1)

如上E-R图所示,personID与idCardNo字段分别是各自表中的主键,而idCardNo又是idCard表的外键(对应person表的personID)

*本文中代码使用的是hibernate4.2.2.final

一对一主键双向关联在hibernate中的代码演示

Person.hbm.xml

<class name="quan.java.hibernate.pojo.Person" table="person" schema="part01">    <id name="personId" type="java.lang.Integer" column="personID">       <generator class="increment"/>    </id>    <property name="personName" type="java.lang.String">        <column name="personName" length="50"/>    </property>    <one-to-one name="idCard" cascade="all" /></class>

IdCard.hbm.xml

<class name="quan.java.hibernate.pojo.IdCard" table="idCard" schema="part01">    <id name="idCardNo" column="idCardNo" >        <generator class="foreign">            <param name="property">person</param>        </generator>    </id>    <one-to-one name="person" constrained="true" />    <property name="idName" column="idName" /></class>
Person.java    private int personId;    private String personName;    private IdCard idCard;IdCard.java    private int idCardNo;    private Person person;    private String idName;

执行代码及结果
效果一

Person person = new Person();person.setPersonName("student_013");IdCard idCard = new IdCard();idCard.setIdName("013");/*此区域中的内容可以改写,后面其它效果的演示只显示这部分的改动start*/idCard.setPerson(person);person.setIdCard(idCard);session.save(person);session.save(idCard);/*此区域中的内容可以改写,后面其它效果的演示只显示这部分的改动end*/transaction.commit();
Hibernate: select max(personID) from personHibernate: insert into part01.person (personName, personID) values (?, ?)Hibernate: insert into part01.idCard (idName, idCardNo) values (?, ?)

效果二

idCard.setPerson(person);person.setIdCard(idCard);/*在效果一的基础上调整了对象保存的先后顺序start*/session.save(idCard);session.save(person);/*在效果一的基础上调整了对象保存的先后顺序start*/
Hibernate: select max(personID) from personHibernate: insert into part01.person (personName, personID) values (?, ?)Hibernate: insert into part01.idCard (idName, idCardNo) values (?, ?)

效果三

idCard.setPerson(person);person.setIdCard(idCard);/*在效果一的基础上屏蔽IDCard对象的保存start*///session.save(idCard);session.save(person);/*在效果一的基础上屏蔽IDCard对象的保存end*/
Hibernate: select max(personID) from personHibernate: insert into part01.person (personName, personID) values (?, ?)Hibernate: insert into part01.idCard (idName, idCardNo) values (?, ?)

效果四

idCard.setPerson(person);person.setIdCard(idCard);/*在效果一的基础上屏蔽Person对象的保存start*/session.save(idCard);//session.save(person);/*在效果一的基础上屏蔽Person对象的保存start*/
Hibernate: select max(personID) from personHibernate: insert into part01.person (personName, personID) values (?, ?)Hibernate: insert into part01.idCard (idName, idCardNo) values (?, ?)

效果五、效果六是在person.hbm.xml文件中将<one-to-one>标签的cascade属性移除后进行测试的
效果五

idCard.setPerson(person);person.setIdCard(idCard);//session.save(idCard);session.save(person);
Hibernate: select max(personID) from personHibernate: insert into part01.person (personName, personID) values (?, ?)

效果六

idCard.setPerson(person);person.setIdCard(idCard);session.save(idCard);//session.save(person);
Hibernate: select max(personID) from personHibernate: insert into part01.person (personName, personID) values (?, ?)Hibernate: insert into part01.idCard (idName, idCardNo) values (?, ?)

结论

  • 对比效果一、效果二、效果三、效果四可以发现无论是调换对象的保存顺序还是只保存其中一个对象,hibernate生成的SQL语句都是一样

  • 对比效果三、效果五可以发现在将主表(person.hbm.xml)中<one-to-noe>标签的级联属性(cascade)移除后,保存主表对象(person)时无法同步保存关联表对象(idCard)

  • 对比效果五、效果六可以发现同样都是移除person.bhm.xml<one-to-one>标签的级联属性(cascade),但保存idCard对象时任会保存person对象

对于效果六中为何仍可以执行级联操作的原因未能弄清楚!

原创粉丝点击