一对一关联包括外键关联和主键关联,今天先讲解外键关联。
其实一对一外键单向关联是多对一单向关联的特殊形式,所以两者在使用上除了注解名称上有所差别外,其他都是一样。到这里大家可以将本节和上一节的进行比较学习。
首先仍然是域模型,不过这里我使用其他名称的域模型,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类(当然,加上了一点点非常简单的注解信息):
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
今天就到这里,后面接着讲一对一单向主键关联。