JPA的一对多映射(双向)

  实体Company:公司。

  实体Employee:雇员。

  Company和Employee是一对多关系。那么在JPA中,如何表示一对多的双向关联呢?

  JPA使用@OneToMany和@ManyToOne来标识一对多的双向关联。一端(Company)使用@OneToMany,多端(Employee)使用@ManyToOne。

  在JPA规范中,一对多的双向关系由多端(Employee)来维护。就是说多端(Employee)为关系维护端,负责关系的增删改查。一端(Company)则为关系被维护端,不能维护关系。

  一端(Company)使用@OneToMany注释的mappedBy="company"属性表明Company是关系被维护端。

  多端(Employee)使用@ManyToOne和@JoinColumn来注释属性company,@ManyToOne表明Employee是多端,@JoinColumn设置在employee表中的关联字段(外键)。

  Company.java如下:

 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 @Entity

21 @Table(name="company")

22 public class Company {

23     

24     @Id

25     @GeneratedValue

26     private Long id;

27     

28     /**公司名称*/

29     @Column(name="name",length=32)

30     private String name;

31     

32     /**拥有的员工*/

33     @OneToMany(mappedBy="company",cascade=CascadeType.ALL,fetch=FetchType.LAZY)

34     //拥有mappedBy注解的实体类为关系被维护端

35     //mappedBy="company"中的company是Employee中的company属性

36     private Set<Employee> employees = new HashSet<Employee>();

37     

38 

39     public Long getId() {

40         return id;

41     }

42 

43     public void setId(Long id) {

44         this.id = id;

45     }

46 

47     public String getName() {

48         return name;

49     }

50 

51     public void setName(String name) {

52         this.name = name;

53     }

54 

55     public Set<Employee> getEmployees() {

56         return employees;

57     }

58 

59     public void setEmployees(Set<Employee> employees) {

60         this.employees = employees;

61     }

62      

63 }

  Employee.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.ManyToOne;

10 import javax.persistence.Table;

11 

12 

13 /**

14  * 雇员

15  * @author Luxh

16  */

17 @Entity

18 @Table(name="employee")

19 public class Employee {

20     

21     @Id

22     @GeneratedValue

23     private Long id;

24     

25     /**雇员姓名*/

26     @Column(name="name")

27     private String name;

28     

29     /**所属公司*/

30     @ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH},optional=false)//可选属性optional=false,表示company不能为空

31     @JoinColumn(name="company_id")//设置在employee表中的关联字段(外键)

32     private Company company;

33 

34     public Company getCompany() {

35         return company;

36     }

37 

38     public void setCompany(Company company) {

39         this.company = company;

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 }

  

  简单的测试用例:

  

 1 package com.cndatacom.jpa.test;

 2 

 3 import java.util.HashSet;

 4 import java.util.Set;

 5 

 6 import javax.persistence.EntityManager;

 7 import javax.persistence.EntityManagerFactory;

 8 import javax.persistence.Persistence;

 9 

10 import org.junit.After;

11 import org.junit.Before;

12 import org.junit.Test;

13 

14 import com.cndatacom.jpa.entity.Author;

15 import com.cndatacom.jpa.entity.Book;

16 import com.cndatacom.jpa.entity.Company;

17 import com.cndatacom.jpa.entity.Employee;

18 

19 

20 public class TestOneToMany {

21     

22 EntityManagerFactory emf = null;

23     

24     @Before

25     public void before() {

26         //根据在persistence.xml中配置的persistence-unit name 创建EntityManagerFactory

27         emf = Persistence.createEntityManagerFactory("myJPA");

28     }

29     

30     @After

31     public void after() {

32          //关闭EntityManagerFactory

33         if(null != emf) {

34             emf.close();

35         }

36     }

37     

38     

39     

40     @Test

41     public void testAddCompany() {

42         EntityManager em = emf.createEntityManager();

43         em.getTransaction().begin();

44         

45         //new 一个公司

46         Company c = new Company();

47         c.setName("Sun");

48         

49         //new 一个雇员

50         Employee e1 = new Employee();

51         e1.setName("陆小凤");

52         //设置所属的公司,必须要设置(实体属性注解使用了optional=false,雇员必须要属于公司,所以公司属性不能为空)

53         e1.setCompany(c);

54         

55         //new 一个雇员

56         Employee e2 = new Employee();

57         e2.setName("花满楼");

58         //设置所属的公司,必须要设置(实体属性注解使用了optional=false,雇员必须要属于公司,所以公司属性不能为空)

59         e2.setCompany(c);

60         

61         //把雇员放到集合中

62         Set<Employee> employees = new HashSet<Employee>();

63         employees.add(e1);

64         employees.add(e2);

65         

66         //设置公司拥有的雇员

67         c.setEmployees(employees);

68         

69         em.persist(c);

70         em.getTransaction().commit();

71         em.close();

72         

73     }

74     

75 

76 }

  

  Employee表的结构:

JPA的一对多映射(双向)

  可以看到Employee表有一个外键字段company_id,就是@JoinColumn(name="company_id")指定的。

 

 

 

  

  

  

你可能感兴趣的:(jpa)