zoukankan      html  css  js  c++  java
  • Hibernate双向一对多级联保存优化

    本文讨论:在Hibernate双向一对多级联保存中,SQL条数过多的问题

     1、建立表结构

    use `hibernate-orm`;
    drop table if exists `orders`;
    drop table if exists `Customer`;
    /* 客户表(单方) */
    create table `Customer`
    (
     id int primary key auto_increment,
     name varchar(50) comment '客户姓名',
     age int comment '客户年龄'
    );
    /* 订单表(多方) */
    create table `orders`
    (
     id int primary key auto_increment,
     name varchar(50) comment '订单名称',
     orderno int comment '订单号',
     customer_id int comment '所属的客户',
     constraint foreign key(`customer_id`) references `Customer`(`id`)
    );
    select * from `orders`;
    select * from `customer`;
    

    2、建立Customer实体对象

    package dai.hao.hibernate.one2many.ano._double;
    import java.util.Set;
    import javax.persistence.CascadeType;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.OneToMany;
    import javax.persistence.Table;
    /**
     * 客户类,单方
     *
     * @author Horace <br/>
     *
     * 2014年8月27日 下午9:08:36
     */
    @Entity
    @Table(name = "Customer")
    public class Customer
    {
     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
     private int id;
     private String name;
     private int age;
     // 设置关联关系
     @OneToMany(targetEntity = Order.class, cascade = CascadeType.ALL)
     // name指定对方表的外键字段
     @JoinColumn(name = "customer_id")
     private Set<Order> orders;
     public Set<Order> getOrders()
     {
      return orders;
     }
     public void setOrders(Set<Order> orders)
     {
      this.orders = orders;
     }
     public Customer()
     {
     }
     public Customer(String name, int age)
     {
      super();
      this.name = name;
      this.age = age;
     }
     public int getId()
     {
      return id;
     }
     public void setId(int id)
     {
      this.id = id;
     }
     public String getName()
     {
      return name;
     }
     public void setName(String name)
     {
      this.name = name;
     }
     public int getAge()
     {
      return age;
     }
     public void setAge(int age)
     {
      this.age = age;
     }
     @Override
     public String toString()
     {
      return "Customer [id=" + id + ", name=" + name + ", age=" + age + "]";
     }
    }
    

    3、建立Order实体对象

    package dai.hao.hibernate.one2many.ano._double;
    import javax.persistence.CascadeType;
    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;
    /**
     * 订单类,多方
     *
     * @author Horace <br/>
     *
     * 2014年8月27日 下午9:09:41
     */
    @Entity
    @Table(name = "orders")
    public class Order
    {
     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
     private int id;
     private String name;
     private int orderno;
     @ManyToOne(targetEntity = Customer.class, cascade = CascadeType.ALL)
     @JoinColumn(name = "customer_id")
     private Customer customer;
     public Customer getCustomer()
     {
      return customer;
     }
     public void setCustomer(Customer customer)
     {
      this.customer = customer;
     }
     public Order()
     {
     }
     public Order(String name, int orderno)
     {
      super();
      this.name = name;
      this.orderno = orderno;
     }
     public int getId()
     {
      return id;
     }
     public void setId(int id)
     {
      this.id = id;
     }
     public String getName()
     {
      return name;
     }
     public void setName(String name)
     {
      this.name = name;
     }
     public int getOrderno()
     {
      return orderno;
     }
     public void setOrderno(int orderno)
     {
      this.orderno = orderno;
     }
     @Override
     public String toString()
     {
      return "Order [id=" + id + ", name=" + name + ", orderno=" + orderno + "]";
     }
    }
    
    4、不需要额外的映射关系的配置文件
    5、执行测试
    package dai.hao.hibernate.one2many.ano._double;
    import java.util.HashSet;
    import java.util.Set;
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    import org.junit.Test;
    public class Main
    {
     @Test
     public void testCascadeAdd()
     {
      // 保存客户级联保存订单
     
      Session session = HiberUtils.getCurrentSession();
      Transaction transaction = session.getTransaction();
      transaction.begin();
     
      Customer customer = new Customer("Horace", 22);
      Order order1 = new Order("订单1", 123456);
      Order order2 = new Order("订单2", 234567);
      Set<Order> orders = new HashSet<Order>();
      orders.add(order1);
      orders.add(order2);
      customer.setOrders(orders);
      session.save(customer);
     
      transaction.commit();
      HiberUtils.close();
     
     }
    }
    

    6、执行结果(双方都维护关联关系的情况下,可以发现多了两条SQL)

    Hibernate: insert into Customer (age, name) values (?, ?)
    Hibernate: insert into orders (customer_id, name, orderno) values (?, ?, ?)
    Hibernate: insert into orders (customer_id, name, orderno) values (?, ?, ?)
    Hibernate: update orders set customer_id=? where id=?
    Hibernate: update orders set customer_id=? where id=?
    

     7、修改Customer实体对象,让多方(Order)维护关联关系

    package dai.hao.hibernate.one2many.ano._double;
    import java.util.Set;
    import javax.persistence.CascadeType;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.OneToMany;
    import javax.persistence.Table;
    /**
     * 客户类,单方
     *
     * @author Horace <br/>
     *
     * 2014年8月27日 下午9:08:36
     */
    @Entity
    @Table(name = "Customer")
    public class Customer
    {
     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
     private int id;
     private String name;
     private int age;
     // 设置关联关系
     /*
      * 在双向关联关系中,mappedBy属性表示由对方维护关联关系,其属性值是对方实体中本方的类属姓名
      * 如:private Customer customer;
      * 相当于xml配置中的inverse="true"。
      * 此时需要注意的是不要写@JoinColumn,因为在本方已经不需要维护关联关系了
      */
     
     @OneToMany(mappedBy="customer", cascade = CascadeType.ALL)
     private Set<Order> orders;
     public Set<Order> getOrders()
     {
      return orders;
     }
     public void setOrders(Set<Order> orders)
     {
      this.orders = orders;
     }
     public Customer()
     {
     }
     public Customer(String name, int age)
     {
      super();
      this.name = name;
      this.age = age;
     }
     public int getId()
     {
      return id;
     }
     public void setId(int id)
     {
      this.id = id;
     }
     public String getName()
     {
      return name;
     }
     public void setName(String name)
     {
      this.name = name;
     }
     public int getAge()
     {
      return age;
     }
     public void setAge(int age)
     {
      this.age = age;
     }
     @Override
     public String toString()
     {
      return "Customer [id=" + id + ", name=" + name + ", age=" + age + "]";
     }
    }
    

    8、测试–注意:测试用例有修改

    package dai.hao.hibernate.one2many.ano._double;
    import java.util.HashSet;
    import java.util.Set;
    import org.hibernate.Session;
    import org.hibernate.Transaction;
    import org.junit.Test;
    public class Main
    {
     @Test
     public void testCascadeAdd()
     {
      // 保存客户级联保存订单
      Session session = HiberUtils.getCurrentSession();
      Transaction transaction = session.getTransaction();
      transaction.begin();
      /**
       * 特别注意: 因为mappedBy是定义在customer中,即Customer类不负责维护级联关系.即维护者是Order.所以,
       * 要将Customer的数据,赋给Order,即用Order的setCustomer()方法去捆定Customer数据;
       */
      Customer customer = new Customer("Horace", 22);
      Order order1 = new Order("订单1", 123456);
      Order order2 = new Order("订单2", 234567);
      Set<Order> orders = new HashSet<Order>();
      orders.add(order1);
      orders.add(order2);
      customer.setOrders(orders);
      order1.setCustomer(customer);
      order2.setCustomer(customer);
      session.save(customer);
      transaction.commit();
      HiberUtils.close();
     }
    }
    

    9、执行结果

    Hibernate: insert into Customer (age, name) values (?, ?)
    Hibernate: insert into orders (customer_id, name, orderno) values (?, ?, ?)
    Hibernate: insert into orders (customer_id, name, orderno) values (?, ?, ?)
    

    总结:在双向关联关系中,需要设置xml–>inverse=”true”,注解:mappedBy=”对方实体中本方属性名”,把关联关系交给多方表控制,那么会省去不必要的SQL,达到优化的效果。

  • 相关阅读:
    Javascript FP-ramdajs
    微信小程序开发
    SPA for HTML5
    One Liners to Impress Your Friends
    Sass (Syntactically Awesome StyleSheets)
    iOS App Icon Template 5.0
    React Native Life Cycle and Communication
    Meteor framework
    RESTful Mongodb
    Server-sent Events
  • 原文地址:https://www.cnblogs.com/horace/p/Horace.html
Copyright © 2011-2022 走看看