JPA使用@OneToOne来标注一对一的关系。
实体City:城市。
实体Mayor:市长。
City和Mayor是一对一的关系。
这里用两种方式描述JPA的一对一关系。一种是通过外键的方式(一个实体通过外键关联到另一个实体的主键);另外一种是通过一张关联表来保存两个实体一对一的关系。
1、通过关联表的方式来保存一对一的关系。
City.java如下:
1 package com.cndatacom.jpa.entity; 2 3 import javax.persistence.CascadeType; 4 import javax.persistence.Column; 5 import javax.persistence.Entity; 6 import javax.persistence.GeneratedValue; 7 import javax.persistence.Id; 8 import javax.persistence.JoinColumn; 9 import javax.persistence.JoinTable; 10 import javax.persistence.OneToOne; 11 import javax.persistence.Table; 12 13 14 15 /** 16 * 城市 17 * @author Luxh 18 */ 19 20 @Entity 21 @Table(name="city") 22 public class City { 23 24 @Id 25 @GeneratedValue 26 private Long id; 27 28 /**城市名称*/ 29 @Column(length=32) 30 private String name; 31 32 /**城市的市长*/ 33 @OneToOne(cascade=CascadeType.ALL)//City是关系的维护端 34 @JoinTable(name="city_mayor",joinColumns=@JoinColumn(name="city_id"),inverseJoinColumns=@JoinColumn(name="mayor_id")) 35 //通过关联表来保存一对一的关系。 36 //定义了一张叫"city_mayor"的表, 37 //joinColumns定义一个外键叫"city_id",指向关系维护端City的主键 38 //inverseJoinColumns定义了一个外键叫"mayor_id",指向关系被维护端Mayor的主键 39 private Mayor mayor; 40 41 42 public Long getId() { 43 return id; 44 } 45 46 public void setId(Long id) { 47 this.id = id; 48 } 49 50 public String getName() { 51 return name; 52 } 53 54 public void setName(String name) { 55 this.name = name; 56 } 57 58 public Mayor getMayor() { 59 return mayor; 60 } 61 62 public void setMayor(Mayor mayor) { 63 this.mayor = mayor; 64 } 65 66 67 68 }
Mayor.java如下:
1 package com.cndatacom.jpa.entity; 2 3 import javax.persistence.CascadeType; 4 import javax.persistence.Column; 5 import javax.persistence.Entity; 6 import javax.persistence.GeneratedValue; 7 import javax.persistence.Id; 8 import javax.persistence.OneToOne; 9 import javax.persistence.Table; 10 11 12 /** 13 * 市长 14 * @author Luxh 15 */ 16 17 @Entity 18 @Table(name="mayor") 19 public class Mayor { 20 21 @Id 22 @GeneratedValue 23 private Long id; 24 25 /**市长姓名*/ 26 @Column(length=32) 27 private String name; 28 29 /**管理的城市*/ 30 @OneToOne(mappedBy="mayor",cascade={CascadeType.MERGE,CascadeType.REFRESH},optional=false) 31 //mappedBy="mayor"表明Mayor是关系被维护端,"mayor"是City实体中的属性 32 private City city; 33 34 public Long getId() { 35 return id; 36 } 37 38 public void setId(Long id) { 39 this.id = id; 40 } 41 42 public String getName() { 43 return name; 44 } 45 46 public void setName(String name) { 47 this.name = name; 48 } 49 50 public City getCity() { 51 return city; 52 } 53 54 public void setCity(City city) { 55 this.city = city; 56 } 57 }
生成的数据库表为:
关联表city_mayor的结构为:
2、通过外键的方式。
City.java如下:
1 package com.cndatacom.jpa.entity; 2 3 import javax.persistence.CascadeType; 4 import javax.persistence.Column; 5 import javax.persistence.Entity; 6 import javax.persistence.GeneratedValue; 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.Fetch; 13 import org.hibernate.annotations.FetchMode; 14 15 16 17 /** 18 * 城市 19 * @author Luxh 20 */ 21 22 @Entity 23 @Table(name="city") 24 public class City { 25 26 @Id 27 @GeneratedValue 28 private Long id; 29 30 /**城市名称*/ 31 @Column(length=32) 32 private String name; 33 34 /**城市的市长*/ 35 @OneToOne(cascade=CascadeType.ALL)//City是关系的维护端 36 @JoinColumn(name="mayor_id")//指定外键的名称 37 @Fetch(FetchMode.JOIN)//会使用left join查询,只产生一条语句 38 //@Fetch(FetchMode.JOIN) 会使用left join查询,只产生一条sql语句(默认使用) 39 //@Fetch(FetchMode.SELECT) 会产生N+1条sql语句 40 //@Fetch(FetchMode.SUBSELECT) 产生两条sql语句 第二条语句使用id in (…..)查询出所有关联的数据 41 private Mayor mayor; 42 public Long getId() { 43 return id; 44 } 45 46 public void setId(Long id) { 47 this.id = id; 48 } 49 50 public String getName() { 51 return name; 52 } 53 54 public void setName(String name) { 55 this.name = name; 56 } 57 58 public Mayor getMayor() { 59 return mayor; 60 } 61 62 public void setMayor(Mayor mayor) { 63 this.mayor = mayor; 64 } 65 66 67 68 }
Mayor.java不变。
这样在数据库只产生两个表,city和mayor。city表结构如下: