Hibernate检索策略之5.3.1一对一单向(外键)关联检索策略——Hibernate4究竟怎么玩

一对一关联包括外键关联和主键关联,今天先讲解外键关联。

其实一对一外键单向关联是多对一单向关联的特殊形式,所以两者在使用上除了注解名称上有所差别外,其他都是一样。到这里大家可以将本节和上一节的进行比较学习。

首先仍然是域模型,不过这里我使用其他名称的域模型,husband和wife这两个模型,在中国这个神奇的国度,是宣扬一夫一妻制的,所以。。。你懂得。

一对一单向主动端:

 1 package com.bao.sample.retrieve.strategy.uoto;
 2 
 3 import javax.persistence.Entity;
 4 import javax.persistence.FetchType;
 5 import javax.persistence.GeneratedValue;
 6 import javax.persistence.GenerationType;
 7 import javax.persistence.Id;
 8 import javax.persistence.JoinColumn;
 9 import javax.persistence.OneToOne;
10 import javax.persistence.Table;
11 
12 import org.hibernate.annotations.Cascade;
13 
14 import com.bao.sample.base.domain.BaseDomain;
15 
16 /**
17  * @Description:一对一单向外键关联  主动端 proactiveness
18  * @author:bao
19  * @date:Sep 3, 2012
20  */
21 @Entity
22 @Table(name = "t_husbanduo")
23 public class HusbandUO extends BaseDomain {
24 
25     private static final long serialVersionUID = 1L;
26 
27     private Integer id;
28     private String name;
29     private WifeUO wife;
30 
31     @Id
32     @GeneratedValue(strategy = GenerationType.AUTO)
33     public Integer getId() {
34         return id;
35     }
36 
37     public void setId(Integer id) {
38         this.id = id;
39     }
40 
41     public String getName() {
42         return name;
43     }
44 
45     public void setName(String name) {
46         this.name = name;
47     }
48 
49     @OneToOne(fetch = FetchType.EAGER)
50     @JoinColumn(name = "wife_id", nullable = false)
51     @Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
52     public WifeUO getWife() {
53         return wife;
54     }
55 
56     public void setWife(WifeUO wife) {
57         this.wife = wife;
58     }
59 
60     public HusbandUO() {
61         super();
62     }
63 
64     public HusbandUO(String name, WifeUO wife) {
65         super();
66         this.name = name;
67         this.wife = wife;
68     }
69 
70 }

看到这个Husband域模型,再与上节中的StudentUM多端域模型进行比较,可以发现了除了@ManyToOne修改成@OneToOne,其他真是一点都没变啊(( ⊙ o ⊙ ))

Wife域模型就不在展开占空间了,就是很简单的一个POJO类(当然,加上了一点点非常简单的注解信息):

WifeUO
 1 package com.bao.sample.retrieve.strategy.uoto;
 2 
 3 import javax.persistence.Entity;
 4 import javax.persistence.GeneratedValue;
 5 import javax.persistence.GenerationType;
 6 import javax.persistence.Id;
 7 import javax.persistence.Table;
 8 
 9 import com.bao.sample.base.domain.BaseDomain;
10 /**
11  * @Description:一对一外键关联 被动端 passiveness
12  * @author:bao
13  * @date:Sep 3, 2012
14  */
15 @Entity
16 @Table(name = "t_wifeuo")
17 public class WifeUO extends BaseDomain {
18 
19     private static final long serialVersionUID = 1L;
20 
21     private Integer id;
22     private String name;
23 
24     @Id
25     @GeneratedValue(strategy = GenerationType.AUTO)
26     public Integer getId() {
27         return id;
28     }
29 
30     public void setId(Integer id) {
31         this.id = id;
32     }
33 
34     public String getName() {
35         return name;
36     }
37 
38     public void setName(String name) {
39         this.name = name;
40     }
41 
42     public WifeUO() {
43         super();
44     }
45 
46     public WifeUO(String name) {
47         super();
48         this.name = name;
49     }
50 
51 }

当然,仍然应该在applicationContext.xml中进行如下配置后,程序便会扫描该包下及其子包下的类注解,不同的注解表示不同的组件。

1     <context:component-scan base-package="com.bao.sample.retrieve.strategy.uoto" />

同时不要忘记在sessionFactory的属性中加入如下信息,否则无法自动找到域模型的。

1         <property name="packagesToScan">
2             <list>
3                 <value>com.bao.sample.retrieve.strategy.uoto*</value>
4             </list>
5         </property>

下面提供了测试方法,有热爱实践的童鞋可以检验一下,俗话说的好啊,实践是检验真理的唯一标准,呵呵。

下面代码是测试延迟加载的。

 1 /**
 2      * @Description:@OneToOne(fetch=FetchType.LAZY)的效果与@ManyToOne(fetch=FetchType.LAZY)是一样的
 3      * 解释参见@StudentAndClassServiceTest.fetchStudentByLazy()
 4      *  void
 5      */
 6     //@Test
 7     public void fetchWifeByLazy() {
 8         HusbandUOService husbandUOService = (HusbandUOService) applicationContext
 9                 .getBean("husbandUOService");
10 
11         HusbandUO husbandUO = husbandUOService.getById(1);
12         WifeUO wifeUO = husbandUO.getWife();
13         System.out.println(wifeUO.getId());
14         System.out.println("------延迟的分割线------");
15         System.out.println(wifeUO.getName());
16     }

本人亲测,输出结果一并显示,正所谓有图有真相,有代码有基情:

 1 Hibernate: 
 2     select
 3         husbanduo0_.id as id11_0_,
 4         husbanduo0_.name as name11_0_,
 5         husbanduo0_.wifeid as wifeid11_0_ 
 6     from
 7         t_husbanduo husbanduo0_ 
 8     where
 9         husbanduo0_.id=?
10 1
11 ------延迟的分割线------

而下面代码是演示迫切加载:

 1     /**
 2      * @Description:@OneToOne(fetch=FetchType.EAGER)的效果与@ManyToOne(fetch=FetchType.EAGER)是一样的
 3      * 解释参见@StudentAndClassServiceTest.fetchStudentByEager()
 4      *  void
 5      */
 6     @Test
 7     public void fetchWifeByEager() {
 8         HusbandUOService husbandUOService = (HusbandUOService) applicationContext
 9                 .getBean("husbandUOService");
10 
11         HusbandUO husbandUO = husbandUOService.getById(1);
12         WifeUO wifeUO = husbandUO.getWife();
13         System.out.println("迫切连接时关联对象类型:" + wifeUO.getClass());
14         System.out.println(wifeUO.getId());
15         System.out.println("------迫切的分割线------");
16         System.out.println(wifeUO.getName());
17     }

输出结果:

 1 Hibernate: 
 2     select
 3         husbanduo0_.id as id11_1_,
 4         husbanduo0_.name as name11_1_,
 5         husbanduo0_.wifeid as wifeid11_1_,
 6         wifeuo1_.id as id12_0_,
 7         wifeuo1_.name as name12_0_ 
 8     from
 9         t_husbanduo husbanduo0_ 
10     inner join
11         t_wifeuo wifeuo1_ 
12             on husbanduo0_.wifeid=wifeuo1_.id 
13     where
14         husbanduo0_.id=?
15 迫切连接时关联对象类型:class com.bao.sample.retrieve.strategy.uoto.WifeUO
16 1
17 ------迫切的分割线------
18 wife

今天就到这里,后面接着讲一对一单向主键关联。

原文地址:https://www.cnblogs.com/geyifan/p/2664502.html