注意:这里说的是一对多的单向关联,不是一对多的双向关联。
实体Author:作者。
实体Book:作者写的书。
Author和Book是一对多的关系。
在JPA中,用@OneToMany来标识一对多的关系。实现一对多的单向关联,只需在代表一的实体(Author)中使用@OneToMany映射标注就可以了,代表多的实体不需要使用任何映射标注。
有两种方式实现一对多的单向关联。一种是在只使用@OneToMany来标识,这种方式是通过一张第三方表来保存关系。还有一种是使用@OneToMany和@JoinColumn来标注,这种方式是在多的一方(Book)的表中增加一个外键列来保存关系。
第一种方式,通过一张第三方表来实现一对多的单向关联:
Author.java如下,需要注意private Set<Book> books = new HashSet<Book>()的注解。只是使用了@OneToMany。
1 package com.cndatacom.jpa.entity; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 import javax.persistence.CascadeType; 7 import javax.persistence.Column; 8 import javax.persistence.Entity; 9 import javax.persistence.FetchType; 10 import javax.persistence.GeneratedValue; 11 import javax.persistence.Id; 12 import javax.persistence.OneToMany; 13 import javax.persistence.Table; 14 15 16 /** 17 * 作者 18 * @author Luxh 19 */ 20 21 @Entity 22 @Table(name="author") 23 public class Author { 24 25 @Id 26 @GeneratedValue 27 private Long id; 28 29 /**作者的名字*/ 30 @Column(length=32) 31 private String name; 32 33 /**作者写的书*/ 34 @OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)//级联保存、更新、删除、刷新;延迟加载 35 private Set<Book> books = new HashSet<Book>(); 36 37 38 39 public Long getId() { 40 return id; 41 } 42 43 44 public void setId(Long id) { 45 this.id = id; 46 } 47 48 49 public String getName() { 50 return name; 51 } 52 53 54 public void setName(String name) { 55 this.name = name; 56 } 57 58 59 public Set<Book> getBooks() { 60 return books; 61 } 62 63 64 public void setBooks(Set<Book> books) { 65 this.books = books; 66 } 67 68 69 70 71 }
Book.java如下,因为是单向的关联,所以这个实体不需要加任何的关联标识。
1 package com.cndatacom.jpa.entity; 2 3 import javax.persistence.Column; 4 import javax.persistence.Entity; 5 import javax.persistence.GeneratedValue; 6 import javax.persistence.Id; 7 import javax.persistence.Table; 8 9 /** 10 * 书 11 * @author Luxh 12 */ 13 14 @Entity 15 @Table(name="book") 16 public class Book { 17 18 @Id 19 @GeneratedValue 20 private Long id; 21 22 /**书名*/ 23 @Column(length=32) 24 private String name; 25 26 public Long getId() { 27 return id; 28 } 29 30 public void setId(Long 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 43 }
只在Author实体中对private Set<Book> books = new HashSet<Book>()加上标注@OneToMany实现单向关联。这样就通过一个关联表来实现这种关联。生成数据库表如下,会以Author的表名和下划线和Book的表名生成一张表author_book来保存Author和Book的一对多单向映射。
在author_book表中,存的是Auhtor的id和Book的id:
第二种方式,通过在多方(Book)的表中增加一个外键列实现一对多的单向关联。
Author.java如下,需要注意private Set<Book> books = new HashSet<Book>()的注解。同时使用了@OneToMany和@JoinColumn。
1 package com.cndatacom.jpa.entity; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 import javax.persistence.CascadeType; 7 import javax.persistence.Column; 8 import javax.persistence.Entity; 9 import javax.persistence.FetchType; 10 import javax.persistence.GeneratedValue; 11 import javax.persistence.Id; 12 import javax.persistence.JoinColumn; 13 import javax.persistence.OneToMany; 14 import javax.persistence.Table; 15 16 17 /** 18 * 作者 19 * @author Luxh 20 */ 21 22 @Entity 23 @Table(name="author") 24 public class Author { 25 26 @Id 27 @GeneratedValue 28 private Long id; 29 30 /**作者的名字*/ 31 @Column(length=32) 32 private String name; 33 34 /**作者写的书*/ 35 @OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY)//级联保存、更新、删除、刷新;延迟加载 36 @JoinColumn(name="author_id")//在book表增加一个外键列来实现一对多的单向关联 37 private Set<Book> books = new HashSet<Book>(); 38 39 40 41 public Long getId() { 42 return id; 43 } 44 45 46 public void setId(Long id) { 47 this.id = id; 48 } 49 50 51 public String getName() { 52 return name; 53 } 54 55 56 public void setName(String name) { 57 this.name = name; 58 } 59 60 61 public Set<Book> getBooks() { 62 return books; 63 } 64 65 66 public void setBooks(Set<Book> books) { 67 this.books = books; 68 } 69 70 71 72 73 }
Book.java不变。
在数据库中只生成了两张表:author和book。
再看book表的结构,会多了一列author_id。