• JPA中实现单向一对多的关联关系


    场景

    JPA入门简介与搭建HelloWorld(附代码下载):

    https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103473937

    JPA中实现单向多对一的关联关系:

    https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103511623

    在上面搭建好JPA的HelloWorld程序后,以及实现单向多对一的关联关系后。

    单向多对一是在Order层添加Customer信息,即在Order实体类中添加

    private Customer customer;

    这样多个Order订单类就能映射到同一个用户,实现单向多对一。

    如果要实现单向一对多的映射关系,就要在Customer层中添加Order的集合,进而实现单向一对多的映射。

    注:

    博客主页:
    https://blog.csdn.net/badao_liumang_qizhi
    关注公众号
    霸道的程序猿
    获取编程相关电子书、教程推送与免费下载。

    实现

    将之前Order中Customer属性注释掉

    package com.badao.jpa.helloworld;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.ManyToOne;
    import javax.persistence.Table;
    
    @Table(name="JPA_ORDERS")
    @Entity
    public class Order {
     private Integer id;
     private String orderName;
    
     //private Customer customer;
    
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     @Id
     public Integer getId() {
      return id;
     }
    
     public void setId(Integer id) {
      this.id = id;
     }
    
     @Column(name="ORDER_NAME")
     public String getOrderName() {
      return orderName;
     }
    
     public void setOrderName(String orderName) {
      this.orderName = orderName;
     }
    
     //映射单向 n-1 的关联关系
     //使用 @ManyToOne 来映射多对一的关联关系
     //使用 @JoinColumn 来映射外键. 
     //可使用 @ManyToOne 的 fetch 属性来修改默认的关联属性的加载策略
     //@JoinColumn(name="CUSTOMER_ID")
     //@ManyToOne
     /*public Customer getCustomer() {
      return customer;
     }
    
     public void setCustomer(Customer customer) {
      this.customer = customer;
     }*/
    }

    然后来到Customer类中添加Order的集合

    private Set<Order> orders = new HashSet<>();
    
    以及相应的set和get方法
    
    public Set<Order> getOrders() {
      return orders;
     }
    
    public void setOrders(Set<Order> orders) {
      this.orders = orders;
     }

    然后在get方法中添加注解

    @JoinColumn(name="CUSTOMER_ID")
     @OneToMany
     public Set<Order> getOrders() {
      return orders;
     }
     public void setOrders(Set<Order> orders) {
      this.orders = orders;
     }

    注:

    使用 @OneToMany 来映射 1-n 的关联关系

    使用 @JoinColumn 来映射外键列的名称

    编写单元测试类进行测试

      

    @Test
      public void testOneToManyPersist(){
       Customer customer = new Customer();
       customer.setAge(18);
       
       customer.setEmail("mm@163.com");
       customer.setLastName("MM");
       
       Order order1 = new Order();
       order1.setOrderName("O-MM-1");
       
       Order order2 = new Order();
       order2.setOrderName("O-MM-2");
       
       //建立关联关系
       customer.getOrders().add(order1);
       customer.getOrders().add(order2);
       
       
       //执行保存操作
       entityManager.persist(customer);
    
       entityManager.persist(order1);
       entityManager.persist(order2);
      }

    运行单元测试类效果

    数据库中订单表

    数据库中用户表

    测试一对多Find方法

    编写单元测试方法

    @Test
      public void testOneToManyFind(){
       Customer customer = entityManager.find(Customer.class, 6);
       System.out.println(customer.getLastName());
       
       System.out.println(customer.getOrders().size());
      }

    运行效果

    注:

    默认对关联的多的一方使用懒加载的加载策略。

    可以使用 @OneToMany 的 fetch 属性来修改默认的加载策略

    比如:@OneToMany(fetch=FetchType.LAZY)

    测试一对多删除方法

    新建单元测试方法

     @Test
     public void testOneToManyRemove(){
      Customer customer = entityManager.find(Customer.class, 8);
      entityManager.remove(customer);
     }

    注:

    默认情况下, 若删除 1 的一端, 则会先把关联的 n 的一端的外键置空,然后进行删除。

    可以通过 @OneToMany 的 cascade属性来修改默认的删除策略。

    比如:@OneToMany(fetch=FetchType.LAZY,cascade={CascadeType.REMOVE})

    测试一对多更新方法

    新建单元测试方法

      @Test
      public void testUpdate(){
       Customer customer = entityManager.find(Customer.class, 6);
       
       customer.getOrders().iterator().next().setOrderName("O-XXX-10");
      }
  • 相关阅读:
    深入Apache NiFi 之源码学习
    Apache NiFi 核心概念和关键特性
    运营商手机视频流量包业务日志ETL及统计分析
    HDP Hive性能调优
    redis 实现登陆次数限制
    Hadoop和Spark的Shuffer过程对比解析
    Scala-基础知识
    Python基础知识问答
    Python基础知识+计算器练习
    Sqoop架构原理及常用命令参数
  • 原文地址:https://www.cnblogs.com/badaoliumangqizhi/p/12033348.html
Copyright © 2020-2023  润新知