Hibernate多对一关联关系

两个持久化类。Customer 和 OrderForm

Customer 类。

package com.zcd.hibernate.manyToOne;

public class Customer
{
    private Integer id;
    private String name;
    
    public Customer()
    {
    }
    
    public Customer(String name)
    {
        this.name = name;
    }

    public Customer(Integer id, String name)
    {
        this.id = id;
        this.name = name;
    }

   //这里省略掉getter 和 setter 方法
    
}

OrderForm 类

package com.zcd.hibernate.manyToOne;

public class OrderForm
{
    private Integer id;
    private String name;
    private Customer customer;
    
    public OrderForm()
    {
    }

    public OrderForm(String name, Customer customer)
    {
        this.name = name;
        this.customer = customer;
    }
    
    public OrderForm(Integer id, String name, Customer customer)
    {
        this.id = id;
        this.name = name;
        this.customer = customer;
    }

   //这里省略掉getter 和 setter 方法
    
}

Customer 和 OrderForm 类的DAO 方法就是没有特别之处,这里也省略的。

//=======================分割线==========================================

下面是测试类调用Service 层。

Service 层的业务方法

public void save(Customer customer, OrderForm orderForm)
    {
        /*
         * OrderForm 为多端, Customer 为一端
         * 这里先保存一端,再保存多端*/
        
        customerDao.save(customer);
        orderFormDao.save(orderForm);
    }

观察现象:这是基于以上 先保存一端,再保存多端的 Service 层的方法的。

//这个方法执行后有两条INSERT语句,能正常保存。
    @Test
    public void testInsert()
    {
        Customer customer = new Customer(1, "顾客");
        
        OrderForm orderForm = new OrderForm(1, "订单1", customer);
        
        testService.save(customer, orderForm);
    }
//但是有一个地方需要注意,如果不做任何改变,继续执行这个方法一次,这里虽然还是指定新建的Customer 对象的id 为1, 
//OrderForm 对象的id 也为1,但是由于是新建的对象,所以在数据库里的他们的id 并不是1,都会在原来的表的基础上加1。比如这里他们的id 都为2,
//那么此时orderform 表中的 id 为 2 的这条数据的外键列的是指向customer 表中的 id 为1 的数据还是 id 为2 的那条数据呢?实际上结果如下图。
//此时orderform 表中的id为2的数据的外键列指向的是customer表中的id为2的那条数据。个人认为是因为,在第二次保存的 orderForm 对象中的属性就是
//第二次保存的customer对象,而那个对象的保存在数据表中的id 为2,所以外键列的值也为2.

 

------------------------------------------------------------------------------------------------------------------------

如果在新建的对象中没有指定id,代码如下

@Test
    public void testInsert()
    {
        Customer customer = new Customer("顾客3");//没有指定id
        
        OrderForm orderForm = new OrderForm("订单3", customer);//没有指定id
        
        testService.save(customer, orderForm);
    }

此时正常保存,需要注意的是,此时也只想数据库发送了两条INSERT 语句(因为这是先保存一端,再保存多端的决定的。),现在看一下,修改Service层,先保存多端,在保存一端.

public void save(Customer customer, OrderForm orderForm)
    {
        /*
         * OrderForm 为多端, Customer 为一端
         * 这里先保存多端,再保存一端*/
        
        orderFormDao.save(orderForm);
        customerDao.save(customer);
    }

此时正常保存,但是向数据库发送了两条INSERT 语句和一条UPDATE语句,说明先保存多端再保存一端的时候性能下降了

================================2017-09-24更============================

为什么先保存多端在保存一端的时候性能会下降呢?

应该是这两个类的关联关系是由多端维护的(也就是在多端的表中有一个外键列保存了一端的ID,因为这样才能把两者关联起来。)

如果我们先保存多端,此时它关联的一端的那条记录还没保存,所以一端的那条记录的ID还没有确定。此时多端的表中的那条记录的外键列还是空的。所以得等到一端保存后再对多端进行更新。

原文地址:https://www.cnblogs.com/GooPolaris/p/7919195.html