• 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")指定的。

      

      

      

  • 相关阅读:
    移动联通电信运营商手机号段分配
    PHP调用内容DES加密的SOAP接口
    微信服务项目表
    微信支付curl出错及错误码解决方案
    微信小店二次开发功能套餐列表
    关于Reactor和Proactor的差别
    ACM-经典DP之Monkey and Banana——hdu1069
    Java怎样处理EXCEL的读取
    android依据区域高度切割文本问题
    合理的keyword密度散布与黑帽SEO之躲藏文本
  • 原文地址:https://www.cnblogs.com/luxh/p/2520501.html
Copyright © 2020-2023  润新知