国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > 互联网 > [置顶] 【SSH进阶之路】Hibernate映射――一对一双向关联映射(六)

[置顶] 【SSH进阶之路】Hibernate映射――一对一双向关联映射(六)

来源:程序员人生   发布时间:2014-11-13 08:59:31 阅读次数:2633次

      上篇博文【SSH进阶之路】Hibernate映照――1对1单向关联映照(5),我们介绍了1对1的单向关联映照,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证端加载人得信息。如图所示:

     

      关键缘由在于对象模型具有方向性:

单向:1端只能加载另外一端,不能反过来。

双向:两端都可以加载另外一端。

      问题来了:如何我们想从身份证端(IdCard)加载人(Person),怎样办呢?

      下面我们开始介绍1对1的双向关联映照。

 

 映照原理

 

       双向关联映照与单向关联映照的原理是1样的,双向关联映照并不影响存储,只影响加载所以,双向关联映照和单向关联映照的关系模型是1样的即http://www.wfuyu.com/db/的表结构是1样的,只是IdCard的实体类和配置文件(IdCard.hbm.xml)产生了1点点变化。

 

 对象模型

 

           

 

 从上图中可以看出:

        1、1个人只有1张身份证,唯1的1个身份证号,对象之间是1对1的关系;

        2、两个对象得关系保护还是由person端决定(由于关系只能由1端保护主键,否则关系就乱了)。

 

       根据上面的对象模型,我们可以看到Person端没有变化,但是要在IdCard端加上Person的援用,例如Person和IdCard实体类以下。

Person

package com.liang.hibernate; public class Person { private int id; private String name; private IdCard idCard; public IdCard getIdCard() { return idCard; } public void setIdCard(IdCard idCard) { this.idCard = idCard; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }

 IdCard

package com.liang.hibernate; public class IdCard { private int id; private String cardNo; private Person person; public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getCardNo() { return cardNo; } public void setCardNo(String cardNo) { this.cardNo = cardNo; } }

 

     不管是单向关联映照还是双向关联映照,他们都属于1对1关联映照,只是他们主键的生成策略不同,分为主键关联映照和唯1外键关联映照。

     由于它们都属于1对1关联映照,所以,Hibernate封装双向关联映照时,主键关键映照和唯1外键关联映照的加载策略1样,都采取的是1对1<one-to-one name=""></one-to-one>,只是属性设置不1致,所以,下面我们分开来看IdCard的配置文件。

 

分类:

 

主键关联映照

 

     同1对1单向关联映照类似,主键关联即利用主键进行关联,关联主键的值相同。下面我们看1下映照文件:

 

IdCard.hbm.xml

<?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 package="com.liang.hibernate"> <class name="IdCard" table="t_idCard"> <id name="id"> <generator class="native"></generator> </id> <property name="cardNo"></property> <!-- 怎样加载对象,抓取策略:join联合查询(默许),select:1条条的查询 --> <one-to-one name="person" class="Person" fetch="join"></one-to-one> </class> </hibernate-mapping>

Person.hbm.xml,同1对1单向主键关联映照1样

<?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 package="com.liang.hibernate"> <class name="Person" table="t_person"> <id name="id"> <!-- 采取foreign生成策略,forgeign会获得关联对象的标识 --> <generator class="foreign" > <param name="property">idCard</param> </generator> </id> <property name="name"></property> <!-- one-to-one唆使hibernate如何加载其关联对象,默许根据主键加载 也就是拿到关系字段值,根据对真个主键来加载关联对象 constrained="true"表示,当前主键(person的主键)还是1个外键 参照了对真个主键(IdCard的主键),也就是会生成外键束缚语句 --> <one-to-one name="idCard" class="IdCard" constrained="true"></one-to-one> </class> </hibernate-mapping>

生成的表结构

 

 

唯1外键关联映照

    

       1对1双向关联映照的外键关联映照也与1对1单向关联映照的外键关联映照类似,在其1对1的指向端(Person)存在1个唯1外键,该唯1外键与被指向端(IdCard)相干联,关联主键的值相同。下面我们看1下映照文件:
 

IdCard.hbm.xml

<?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 package="com.liang.hibernate"> <class name="IdCard" table="t_idCard"> <id name="id"> <generator class="native"></generator> </id> <property name="cardNo"></property> <!-- 1对1唯1外键关联双向采取<one-to-one>标签来映照,必须指定<one-to-one> 标签中的property-ref属性为关系字段的名称 --> <one-to-one name="person" class="Person" property-ref="idCard"></one-to-one> </class> </hibernate-mapping>

Person.hbm.xml,同1对1单向唯1外键关联映照1样

<?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 package="com.liang.hibernate"> <class name="Person" table="t_person"> <id name="id"> <generator class="native" ></generator> </id> <property name="name"></property> <!-- 由于它是1对1的唯1外键关联,它是多对1关联的特例,注释可以直接写成多对1关联--> <!-- idCard属性,表达的是本对象与IdCard的多对1关系。 --> <many-to-one name="idCard" class="IdCard" column="idCardId" unique="true"></many-to-one> </class> </hibernate-mapping>

生成的表结构

       

 

对照

 

       1对1单向和双向关联映照的区分正是对象模型和关系模型的区分之1。

对象模型:有方向性。它究竟是单向还是双向是由对象模型决定的即配置文件决定。

关系模型:没有方向性或说是双向的。从任何1端都可以加载另外一端。

 

下载

 

         以上内容,只证明了1对1双向关联映照不影响存储即没有改变表结构,但不能证明关联是双向的,需要写相应的测试用例,我们以源码的情势给大家。源码下载

 

 总结

 

       1对1双向关联映照其实不是必须的,是由需求下决定的。如果没有这样的需求,用户也没有要求,系统也不需要,就没有必要建立双向的关联映照。

 

 

      下篇博文,我们介绍多对多单向关联映照,谢谢关注。

 

生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生