zoukankan      html  css  js  c++  java
  • JPA 系列教程4-单向一对多

    JPA中的@OneToMany

    @Target({METHOD, FIELD}) @Retention(RUNTIME)
    public @interface OneToMany {
        Class targetEntity() default void.class;
        CascadeType[] cascade() default {};
        FetchType fetch() default EAGER;
        String mappedBy() default "";
        boolean orphanRemoval() default false;
    }

    主要属性
    - # targetEntity属性表示默认关联的实体类型,默认为当前标注的实体类;
    因为一对多的实体集合时保存在集合类中,因此必须指明集合类中保存的具体类型:
    1)指定集合泛型的具体类型;如:Set getProducts() {…
    2)指定targetEntity属性类型;如:@OneToMany(targetEntity=Product.class,casade={CascadeTypeType.ALL})
    - # cascade属性表示与此实体一对一关联的实体的联级样式类型。联级样式上当对实体进行操作时的策略。
    说明:在定义关系时经常会涉及是否定义Cascade(级联处理)属性,担心造成负面影响.
    ·不定义,则对关系表不会产生任何影响
    ·CascadeType.PERSIST (级联新建)
    ·CascadeType.REMOVE (级联删除)
    ·CascadeType.REFRESH (级联刷新)
    ·CascadeType.MERGE (级联更新)中选择一个或多个。
    ·还有一个选择是使用CascadeType.ALL ,表示选择全部四项
    - # fetch属性是该实体的加载方式,有两种:LAZY和EAGER。默认为惰性加载,一般也建议使用惰性加载。
    - # mappedBy属性用于双向关联实体时使用。
    - # orphanRemoval属性用于双向关联实体时使用。

    单向一对多(@OneToMany)关联是比较少用的(一般用双向一对多代替)。一个商品类型对应多个商品,通过商品类型可以获得该商品类型的多个商品的信息,商品类型和商品就是一对多的关系。

    单向一对多表的ddl语句

    同单向多对一表的ddl语句一致

    Product

    package com.jege.jpa.one2many;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    /**
     * @author JE哥
     * @email 1272434821@qq.com
     * @description:单向
     */
    @Entity
    @Table(name = "t_product")
    public class Product {
      @Id
      @GeneratedValue
      private Long id;
      private String name;
    
      public Product() {
    
      }
    
      public Product(String name) {
        this.name = name;
      }
    
      public Long getId() {
        return id;
      }
    
      public void setId(Long id) {
        this.id = id;
      }
    
      public String getName() {
        return name;
      }
    
      public void setName(String name) {
        this.name = name;
      }
    
      @Override
      public String toString() {
        return "Product [id=" + id + ", name=" + name + "]";
      }
    
    }
    
    

    ProductType

    package com.jege.jpa.one2many;
    
    import java.util.HashSet;
    import java.util.Set;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.OneToMany;
    import javax.persistence.Table;
    
    /**
     * @author JE哥
     * @email 1272434821@qq.com
     * @description:单向:一个产品类型下面有多个产品
     */
    @Entity
    @Table(name = "t_product_type")
    public class ProductType {
      @Id
      @GeneratedValue
      private Long id;
      private String name;
      // 一对多:集合Set
      @OneToMany
      @JoinColumn(name = "type_id")
      private Set<Product> products = new HashSet<Product>();
    
      public Long getId() {
        return id;
      }
    
      public void setId(Long id) {
        this.id = id;
      }
    
      public String getName() {
        return name;
      }
    
      public void setName(String name) {
        this.name = name;
      }
    
      public Set<Product> getProducts() {
        return products;
      }
    
      public void setProducts(Set<Product> products) {
        this.products = products;
      }
    
      @Override
      public String toString() {
        return "ProductType [id=" + id + ", name=" + name + "]";
      }
    
    }
    
    

    One2ManyTest

    package com.jege.jpa.one2many;
    
    import java.util.Set;
    
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.Persistence;
    
    import org.junit.After;
    import org.junit.AfterClass;
    import org.junit.Before;
    import org.junit.BeforeClass;
    import org.junit.Test;
    
    /**
     * @author JE哥
     * @email 1272434821@qq.com
     * @description:单向一对多Test
     */
    public class One2ManyTest {
      private static EntityManagerFactory entityManagerFactory = null;
      private EntityManager entityManager = null;
    
      @BeforeClass
      public static void setUpBeforeClass() throws Exception {
        entityManagerFactory = Persistence.createEntityManagerFactory("com.jege.jpa");
      }
    
      // 一次性保存1一个商品类型,保存这个商品类型下面的2个产品商品
      // 不过无论怎样调整保存一方商品类型,还是保存多方商品的顺序,都会出现多余的update语句,从而影响性能
      @Before
      public void persist() throws Exception {
        entityManager = entityManagerFactory.createEntityManager();
        entityManager.getTransaction().begin();
    
        ProductType type = new ProductType();
        type.setName("商品类型类型1");
    
        Product product1 = new Product("商品1");
        Product product2 = new Product("商品2");
    
        // 只能从一方建立到多方的关系
        type.getProducts().add(product1);
        type.getProducts().add(product2);// 临时状态
    
        entityManager.persist(type);// 持久化状态 1 类型1
        entityManager.persist(product1);// 持久化状态,只保存了name属性,type_id没有保存:1 商品1 null
        entityManager.persist(product2);// 持久化状态,只保存了name属性,type_id没有保存:2 商品2 null
    
        // type.getProducts(商品1的id=1,商品2的id=2)出现脏数据
        // 脏数据在当前事务范围内出现,2条更新语句
      }
    
      @Test
      public void find() throws Exception {
        System.out.println("---------------------");
        // 不能通过一方获取多方集合是否为null,来判断是否一方是否有多方的数据,只能通过一方获取多方集合.size()来判断
        ProductType type = entityManager.find(ProductType.class, 1L);
        System.out.println(type);
        Set<Product> products = type.getProducts();
        if (products.size() > 0) {
          System.out.println("当前商品类型下面是有商品的");
        } else {
          System.out.println("当前商品类型下面是没有商品的");
        }
      }
    
    
      @After
      public void tearDown() throws Exception {
        entityManager.getTransaction().commit();
        if (entityManager != null && entityManager.isOpen())
          entityManager.close();
      }
    
      @AfterClass
      public static void tearDownAfterClass() throws Exception {
        if (entityManagerFactory != null && entityManagerFactory.isOpen())
          entityManagerFactory.close();
      }
    
    }
    

    其他关联项目

    源码地址

    https://github.com/je-ge/jpa

    如果觉得我的文章对您有帮助,请打赏支持。您的支持将鼓励我继续创作!谢谢!
    微信打赏
    支付宝打赏

  • 相关阅读:
    linux C总结篇(进程)
    进程与线程的区分
    递归的两种思路
    Linux下git与github的一般使用
    文件读写和文件指针的移动
    文件的创建,打开与关闭
    一个简单脚本
    linux 三剑客命令(grep,sed ,awk)
    常用正则表达式
    PAT:1002. A+B for Polynomials (25) 部分错误
  • 原文地址:https://www.cnblogs.com/je-ge/p/6158825.html
Copyright © 2011-2022 走看看