01一对一关联关系.doc

上传人:11****ws 文档编号:3255451 上传时间:2019-05-27 格式:DOC 页数:6 大小:51KB
下载 相关 举报
01一对一关联关系.doc_第1页
第1页 / 共6页
01一对一关联关系.doc_第2页
第2页 / 共6页
01一对一关联关系.doc_第3页
第3页 / 共6页
01一对一关联关系.doc_第4页
第4页 / 共6页
01一对一关联关系.doc_第5页
第5页 / 共6页
点击查看更多>>
资源描述

1、一对一关联关系创建 POJO 对象妻子和丈夫是一对一的关系,基于这种关系,设计类时在妻子类中保存一个丈夫类型的引用,同样在丈夫类中保存一个妻子类型的用。Wife 类: id name Husband 类型的属性:husbandHusband 类: id name Wife 类型的属性:wife不要忘了生成 Getter 和 Setter 方法创建映射文件在建立映射的时候可以从一方入手,要么从妻子找到丈夫,要么从丈夫找到妻子,这里采用后者,即丈夫的 id 来源于妻子的 id(夫妻具有相同的 id) ,建立映射文件的时候要注意,需要同时在妻子和丈夫的映射文件中添加 one-to-one 元素, n

2、ame 属性指定类中定义的引用类型的属性名;还要对丈夫映射文件中的 id 元素的配置项进行修改,将生成器设为foreign 类型,添加一个 param 子元素,参数名为 property,值为类中定义的引用类型的属性名。在丈夫映射文件的 one-to-one 元素下配置 constrained 属性为 true,则可将这种外键关联反映到数据库表结构中(即为丈夫表建立外键约束) 。Wife.hbm.xml 文件Husband.hbm.xml 文件wife上面的映射文件的配置可以通过丈夫找到妻子,若要保存一条丈夫记录,则必须要为丈夫对象设置妻子类型的属性,这样只需要保存丈夫对象,则其持有的妻子对象

3、中的信息也会与数据库同步,看下面的代码:static void saveHusband() Session s = null;Transaction tx = null;try Wife w1 = new Wife();w1.setName(“wife1“);Husband h1 = new Husband();h1.setName(“husband1“);h1.setWife(w1);s = HibernateUtil.getSession();tx = s.beginTransaction();s.save(h1);mit(); finally if (s != null) s.close

4、();这样的话只插入丈夫的记录,如果关联的妻子的记录不存在,就会添加妻子记录到数据库中。在一个事务中先保存了丈夫对象,再修改其持有的妻子对象的属性,更新同样会反映到数据库中在上面代码的 save 之后再次修改妻子属性值,如s.save(h1);w1.setName(“wife1_new_name“);在 hibernate 底层生成的两条 insert 语句之后还有伴随一条 update 语句更新妻子记录。反过来即使妻子对象中设置了丈夫类型的属性,只保存妻子对象,只会将妻子信息保存到数据库中,如下代码片段所示:Wife w1 = new Wife();w1.setName(“wife1“);H

5、usband h1 = new Husband();h1.setName(“husband1“);w1.setHusband(h1);s = HibernateUtil.getSession();tx = s.beginTransaction();s.save(w1);mit();我们将看到最后插入到数据库中的只是妻子记录,而与之关联的丈夫对象并没有插入到数据库中,这样插入数据的时候就成了单向的一对一关联,其实插入数据无所谓单向还是双向,单双向的说法是在检索数据的时候使用的。一对一关联关系的检索我们已经知道了加载对象时采用get和采用load方法的区别(load采用延迟加载,访问属性时才主动加

6、载) ,但是这里要注意一个问题,从丈夫加载妻子(从表加载主表)如果我们在丈夫映射文件中的one-to-one 元素下指定了constrained=“true“ ,那么丈夫表的id就成了参照妻子表的外键,这时从丈夫加载妻子属性,无论是采用get还是load,都采用延迟加载,解决办法如下代码所示:保存记录的方法,返回id,便于检索:static int saveHusband() Session s = null;Transaction tx = null;try Wife w1 = new Wife();w1.setName(“wife1“);Husband h1 = new Husband()

7、;h1.setName(“husband1“);h1.setWife(w1);s = HibernateUtil.getSession();tx = s.beginTransaction();int id = (Integer)s.save(h1);mit();return id; finally if (s != null) s.close();查找丈夫的方法static Husband getHusband(int id) Session s = null;try s = HibernateUtil.getSession();Husband h = (Husband)s.get(Husba

8、nd.class, id);Hibernate.initialize(h.getWife();return h; finally if (s != null) s.close();黑体字为即时加载方法,因为在数据库表中建立了丈夫表到妻子表的外键关联,hibernate对于get方法也采用了延迟加载(若丈夫映射中不配constrained=“true“,get仍可立即得到丈夫对象) ,但是反过来从妻子找丈夫就没有任何问题了。代码如下:static Wife getWife(int id) Session s = null;try s = HibernateUtil.getSession();Wi

9、fe w = (Wife)s.get(Wife.class, id);return w; finally if (s != null) s.close();main方法中的测试代码:Husband h1 = getHusband(saveHusband();System.out.println(h1.getWife().getName();Wife w1 = getWife(1);System.out.println(w1.getHusband().getName();注意:查询主表和查询从表有一个区别,反映在底层的失去了语句上,查询主表对象时,会采用连接查询同时关联从表,查出从表中的关联记录

10、,这样我们再加载关联的丈夫对象时就不会再生成查询语句了。为一对一关联关系配置映射的时候除了上面的映射配置外,还可以用以下方式来配置丈夫映射文件Husband.hbm.xmlWife.hbm.xml说明:这里我们指定了从丈夫找妻子的时候采用的是外键关联,并且外键是唯一的,其实还是一对一的关联,基于这种表结构的外键关联,如果要保存一条丈夫记录,并且丈夫对象中持有一个妻子对象的引用,当当通过丈夫对象提供的信息(丈夫的 id) ,根本无从获取妻子对象的 id,那么该妻子对象就无法与数据库同步了。所以还要手动保存,妻子对象,否则会抛异常。这和第一种配置映射下主键关联是不同。查询时根据丈夫查妻子,无论使用

11、 get 还是 load,对妻子对象(主表对象)的加载都是延迟加载(这种情况就是在数据库底层设置了外键关联,前面已经讲过了) ,可以在加载到丈夫对象后采用 Hibernate.initialize(h.getWife();解决。必须要在妻子映射文件 one-to-one 元素中配置 property-ref 属性值为丈夫类中定义的妻子引用类型属性名,这是从对象的关系考虑的,即判断丈夫对象所引用的妻子对象是不是她自身,而 hibernate 底层会将这种对象的实体关联转化为数据库的外键关联,即从丈夫表出发,从某种意义上来说说双向关联,本质上还是单向关联!即,从妻子找丈夫,可转化为从丈夫找妻子,只是丈夫手中已握有妻子的 id 了。进一步可以这样分析,property-ref 属性是基于对象关系的,而 column 属性是基于数据库关系的,若均不指定one-to-one 关联是居于主键是否相等的判断,这样的话从妻子查出的丈夫就会依据丈夫 id是否与妻子相等,不合逻辑了。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 重点行业资料库 > 医药卫生

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。