北在北方

太白枝头看,花开不计年,杯中浮日月,楼外是青天。

导航

JPA的一对一映射

Posted on 2012-05-28 22:16  CN.programmer.Luxh  阅读(5414)  评论(6编辑  收藏  举报

  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表结构如下: