已经有段时间没有写博客了,总是这样那样的事情牵绊,不过深入学习测试依然继续,只是没有定时更新博客而已,抱歉了。
上节讲了一对一单向外键关联,这次讲一对一单向主键关联。
当然,主键关联和外键关联很相似,唯一的区别就是前者通过主动端主键把二者联系在一起,而后者通过主动端的外键联系在一起。还以Husband和Wife域模型为例,一对一种这个例子最好了,尤其是在中国。
先看一下被动端:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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来做了吧,这点应该没错。
其他的使用与外键关联就一致了,在此就不在赘述了。