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

已经有段时间没有写博客了,总是这样那样的事情牵绊,不过深入学习测试依然继续,只是没有定时更新博客而已,抱歉了。

上节讲了一对一单向外键关联,这次讲一对一单向主键关联。

当然,主键关联和外键关联很相似,唯一的区别就是前者通过主动端主键把二者联系在一起,而后者通过主动端的外键联系在一起。还以Husband和Wife域模型为例,一对一种这个例子最好了,尤其是在中国。

先看一下被动端:

HusbandUOP
 1 package com.bao.sample.retrieve.strategy.uotop;
 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 primarykey
12  * @author:bao
13  * @date:Sep 3, 2012
14  */
15 @Entity
16 @Table(name = "t_husbanduop")
17 public class HusbandUOP 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 HusbandUOP() {
43         super();
44     }
45 
46     public HusbandUOP(String name) {
47         super();
48         this.name = name;
49     }
50 
51 }

这里说被动段似乎不是很恰当,虽然从java代码看,从husband是无法导航出wife,不过,先卖个关子,大家可以看后面的DDL建表语句上。

主动端域代码:

 1 package com.bao.sample.retrieve.strategy.uotop;
 2 
 3 import javax.persistence.Entity;
 4 import javax.persistence.FetchType;
 5 import javax.persistence.GeneratedValue;
 6 import javax.persistence.Id;
 7 import javax.persistence.OneToOne;
 8 import javax.persistence.PrimaryKeyJoinColumn;
 9 import javax.persistence.Table;
10 
11 import org.hibernate.annotations.Cascade;
12 import org.hibernate.annotations.CascadeType;
13 import org.hibernate.annotations.GenericGenerator;
14 import org.hibernate.annotations.Parameter;
15 
16 import com.bao.sample.base.domain.BaseDomain;
17 
18 /**
19  * @Description:一对一单向主键关联  主动端 proactiveness primarykey
20  * @author:bao
21  * @date:Sep 3, 2012
22  */
23 @Entity
24 @Table(name = "t_wifeuop")
25 public class WifeUOP extends BaseDomain {
26 
27     private static final long serialVersionUID = 1L;
28 
29     private Integer id;
30     private String name;
31     private HusbandUOP husband;
32 
33     @Id
34     @GeneratedValue(generator = "wifeGenerator")
35     @GenericGenerator(name = "wifeGenerator", strategy = "foreign", 
36             parameters = { @Parameter(name = "property", value = "husband") })
37     public Integer getId() {
38         return id;
39     }
40 
41     public void setId(Integer id) {
42         this.id = id;
43     }
44 
45     public String getName() {
46         return name;
47     }
48 
49     public void setName(String name) {
50         this.name = name;
51     }
52 
53     @OneToOne(fetch = FetchType.LAZY)
54     @PrimaryKeyJoinColumn
55     @Cascade(CascadeType.SAVE_UPDATE)
56     public HusbandUOP getHusband() {
57         return husband;
58     }
59 
60     public void setHusband(HusbandUOP husband) {
61         this.husband = husband;
62     }
63 
64     public WifeUOP() {
65         super();
66     }
67 
68     public WifeUOP(String name, HusbandUOP husband) {
69         super();
70         this.name = name;
71         this.husband = husband;
72     }
73 
74 }

在这里需要重点看一下wife域模型的id生成方式,wife是这里的含义是使用另一个相关对象husband的主键做为wife的主键。但这并不体现先sql语句中。

 1 package com.bao.sample.retrieve.strategy.uotop;
 2 
 3 import org.junit.Test;
 4 import org.springframework.context.ApplicationContext;
 5 import org.unitils.UnitilsJUnit4;
 6 import org.unitils.spring.annotation.SpringApplicationContext;
 7 
 8 public class HusbandAndWifeServiceTest extends UnitilsJUnit4 {
 9 
10     @SpringApplicationContext({ "applicationContext.xml" })
11     private ApplicationContext applicationContext;
12 
13     /**
14      * @Description 级联保存<br />
15      *              主动端关联被动端对象的get方法上的注解为//@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
16      * 
17      */
18     @Test
19     public void saveHusbandAndWifeWithCascade() {
20         HusbandUOPService husbandUOPService = (HusbandUOPService) applicationContext.getBean("husbandUOPService");
21 
22         HusbandUOP wifeUO = new HusbandUOP("wife4");
23         husbandUOPService.save(new WifeUOP("husband4", wifeUO));
24 
25     }
26 
27 }

具体的sql语句我已经输出出来:

 1 Hibernate: 
 2     drop table if exists t_husbanduop
 3 Hibernate: 
 4     drop table if exists t_wifeuop
 5 Hibernate: 
 6     create table t_husbanduop (
 7         id integer not null auto_increment,
 8         name varchar(255),
 9         primary key (id)
10     )
11 Hibernate: 
12     create table t_wifeuop (
13         id integer not null,
14         name varchar(255),
15         primary key (id)
16     )
17 Hibernate: 
18     insert 
19     into
20         t_husbanduop
21         (name) 
22     values
23         (?)
24 Hibernate: 
25     insert 
26     into
27         t_wifeuop
28         (name, id) 
29     values
30         (?, ?)

从DDL语句中可以看到,t_husbanduop表示自增的,而t_wifeuop却没有,这内部同步两个表主键的工作我想hibernate来做了吧,这点应该没错。
其他的使用与外键关联就一致了,在此就不在赘述了。

posted @ 2012-09-12 22:15  葛一凡  阅读(395)  评论(0编辑  收藏  举报