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表的結構:

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

 

 

 

  

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM