JPA 单向一对多关联关系

Posted javaobject

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JPA 单向一对多关联关系相关的知识,希望对你有一定的参考价值。

 

映射单向一对多的关联关系

1、首先在一的一端加入多的一端的实体类集合

2、使用@OneToMany 来映射一对多的关联关系
3、使用@JoinColumn 来映射外键列的名称
4、可以使用@OneToMany的fetch 属性来修改默认的加载策略
5、可以通过@OneToMany的cascade 属性来修改默认的删除策略
6、cascade={CascadeType.REMOVE} 会把主表和从表的数据都删除

如下代码:

/**
 *数据库持久化类
 * @author z
 *
 */
@Table(name="JPA_CUSTOMERS")//主要是映射表名对应的数据库表名JPA_CUSTOMER默认情况下可以不写表名与持久化类名相同
@Entity //表明这是一个持久化类
public class Customer {
    
    private Integer id;
    private String lastName;
    private String email;
    private int  age ;
    
    private Date createdTime;
    private Date birth;
    
    /**
     * 单向一对多关系映射
     * 1、添加多的一方的集合属性
     */
      private Set<Order> orders=new HashSet<>();
    
    /**
     * 定义各数据列必须加在get方法上
     * @return
     */
    //定义主键,生成主键的策略AUTO自动的根据数据的类型生成主键
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Id //定义数据列
//    @Column(name="ID")//定义数据库的列名如果与字段名一样可以省略
    
    //使用table生成主键
//    @TableGenerator(name="ID_GENERATOR",
//            table="JPA_ID_GENERATORS",
//            pkColumnName="PK_NAME",
//            pkColumnValue="CUSTOMER_ID",
//            valueColumnName="PK_VALUE",
//            allocationSize=100
//            
//            
//            )
//    
//    @GeneratedValue(strategy=GenerationType.TABLE,generator="ID_GENERATOR")
//    @Id
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    
    @Column(name="LAST_NAME",length=50,nullable=false) //nullable false表示此字段不能为空
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    
    @Temporal(TemporalType.TIMESTAMP)
    public Date getCreatedTime() {
        return createdTime;
    }
    public void setCreatedTime(Date createdTime) {
        this.createdTime = createdTime;
    }
    @Temporal(TemporalType.DATE)
    public Date getBirth() {
        return birth;
    }
    public void setBirth(Date birth) {
        this.birth = birth;
    }
    
    //映射单向一对多的关联关系
    //使用@OneToMany 来映射一对多的关联关系
    //使用@JoinColumn 来映射外键列的名称
    //可以使用@OneToMany的fetch 属性来修改默认的加载策略
    //可以通过@OneToMany的cascade 属性来修改默认的删除策略
    //cascade={CascadeType.REMOVE} 会把主表和从表的数据都删除
    @JoinColumn(name="CUSTOMER_ID")
    @OneToMany(fetch=FetchType.EAGER,cascade={CascadeType.REMOVE})
   public Set<Order> getOrders() { 
        return orders;
    }
    public void setOrders(Set<Order> orders) {
        this.orders = orders;
    }
    
    //工具方法,不需要映射为数据表的一列
    @Transient
    public String getInfo(){
        return "lastName:"+lastName+",email:"+email;
    }
    @Override
    public String toString() {
        return "Customer [id=" + id + ", lastName=" + lastName + ", email=" + email + ", age=" + age + ", createdTime="
                + createdTime + ", birth=" + birth + "]";
    }
    
}

2、单向多对一增删查改测试范例及注意事项
public class JPATest {
    private EntityManagerFactory entityManagerFactory;
    private EntityManager entityManager;
    private EntityTransaction transaction;
    @Before
    public void init(){
        entityManagerFactory= Persistence.createEntityManagerFactory("jpa-1");
        entityManager=entityManagerFactory.createEntityManager();
        transaction=entityManager.getTransaction();
        transaction.begin();//开启事务
        
    }
    @After
    public void destroy(){
        transaction.commit();
        entityManager.close();
        entityManagerFactory.close();
    }
    
    //修改
    @Test
    public void testUpdate(){
        Customer customer=entityManager.find(Customer.class, 4);
        customer.getOrders().iterator().next().setOrderName("O-XXX-10");
        
    }
    
     //删除
    //默认情况下,若删除1的一端,则会先把关联的多的一段的外键置空,然后删除一的一端
    ////可以通过@OneToMany的cascade 属性来修改默认的删除策略
    @Test
    public void testOneToManyRemove(){
        Customer customer=entityManager.find(Customer.class, 7);
        entityManager.remove(customer);
        
    }
    
    //默认对关联多的一方使用懒加载的加载策略(延迟加载)
    //可以使用@OneToMany的fetch 属性来修改默认的加载策略
    //查询
    @Test
    public void testOneToManyFind(){
        Customer customer=entityManager.find(Customer.class,6);
        System.out.println(customer.getLastName());
        
        System.out.println(customer.getOrders().size());
        
    }
    
    //单向一对多保存时,一定会多出update语句
    //因为多的一端在插入时不会同时插入外键列
    //保存
    @Test
    public void testOneToManyPersist(){
        Customer customer=new Customer();
        customer.setAge(16);
        customer.setBirth(new Date());
        customer.setCreatedTime(new Date());
        customer.setEmail("[email protected]");
        customer.setLastName("AA");
        
        Order order1=new Order();
        order1.setOrderName("o-CC-1");
        
        Order order2=new Order();
        order2.setOrderName("o-CC-2");
        
        //建立关联关系
        customer.getOrders().add(order1);
        customer.getOrders().add(order2);
        //执行保存操作
        entityManager.persist(customer);
        entityManager.persist(order1);
        entityManager.persist(order2);    
     }   
    }

源码地址:https://github.com/wuhongpu/JPA.git

 

 

以上是关于JPA 单向一对多关联关系的主要内容,如果未能解决你的问题,请参考以下文章

JPA一对多单向

JPA映射关系

JPA - 使用 EclipseLink 保持单向一对多关系失败

JPA:映射关联关系------映射单向多对一的关联关系

springboot JPA 一对多关联查询 ,动态复杂查询 去除重复数据 in语句使用

Jpa之关联对象(单向多对多)