双向关联产生多余的SQL语句

/**
* 添加一个订单到id为6的客户中
*/
@Test
public void fun1(){
Session session = HibernateUtils.getSession();
session.getTransaction().begin(); try {
Customer cst = session.get(Customer.class, 6); Order od = new Order();
od.setDetail_id(UUID.randomUUID().toString()); cst.getOds().add(od);
} catch (Exception e) {
session.getTransaction().rollback();
// TODO Auto-generated catch block
e.printStackTrace();
} session.getTransaction().commit();
}

 

这是Hibernate生成的语句:

Hibernate:
    select
        customer0_.cust_id as cust_id1_0_0_,
        customer0_.cust_name as cust_nam2_0_0_,
        customer0_.cust_gender as cust_gen3_0_0_,
        customer0_.cust_age as cust_age4_0_0_,
        customer0_.cust_phone as cust_pho5_0_0_
    from
        customera customer0_
    where
        customer0_.cust_id=?
Hibernate:
    select
        ods0_.cust_order_id as cust_ord3_1_0_,
        ods0_.order_id as order_id1_1_0_,
        ods0_.order_id as order_id1_1_1_,
        ods0_.detail_id as detail_i2_1_1_,
        ods0_.cust_order_id as cust_ord3_1_1_
    from
        ordersa ods0_
    where
        ods0_.cust_order_id=?
Hibernate:
    insert
    into
        ordersa
        (detail_id, cust_order_id, order_id)
    values
        (?, ?, ?)
Hibernate:
    update
        ordersa
    set
        cust_order_id=?
    where
        order_id=?
很容易发现,对于外键属性,cust_order_id,hibernate进行了两次维护,即进行了两次更新,这明显对性能有影响。如何减少这类SQL语句的生成,就得用到inverse了。

如何会有两次维护外键的语句生成?

  因为双向维护关系,而且持久态对象可以自动更新数据库,更新客户的时候会修改一次外键,更新订单的时候同样也会修改一次外键。这样就会产生了多余的SQL。

解决方法:

  只需要将一方放弃外键维护权即可。也就是说关系不是双方维护的,只需要交给某一方去维护就可以了。通常我们都是交给多的一方去维护的,为什么呢?因为多的一方才是维护关系的最好的地方,举个例子:一个老师对应多个学生,一个学生对应一个老师,这是典型的一对多。那么一个老师如果记住了所有学生的名字是很难得,但如果让每个学生记住老师的名字应该不难。所以在一对多中,一的一方都会放弃外键的维护权(关系的维护)。这个时候如果想让一的一方放弃外键的维护权只需要

  在一的一方中有如下配置(customer.hbm.xml)

  

<!-- 配置一对多属性 -->
<set name="ods" cascade="save-update" inverse="true">
<key column="cust_order_id"></key>
<one-to-many class="Order"/>
</set>

  再次执行上述java的添加订单的代码

  Hibernate:
    select
        customer0_.cust_id as cust_id1_0_0_,
        customer0_.cust_name as cust_nam2_0_0_,
        customer0_.cust_gender as cust_gen3_0_0_,
        customer0_.cust_age as cust_age4_0_0_,
        customer0_.cust_phone as cust_pho5_0_0_
    from
        customera customer0_
    where
        customer0_.cust_id=?
Hibernate:
    select
        ods0_.cust_order_id as cust_ord3_1_0_,
        ods0_.order_id as order_id1_1_0_,
        ods0_.order_id as order_id1_1_1_,
        ods0_.detail_id as detail_i2_1_1_,
        ods0_.cust_order_id as cust_ord3_1_1_
    from
        ordersa ods0_
    where
        ods0_.cust_order_id=?
Hibernate:
    insert
    into
        ordersa
        (detail_id, cust_order_id, order_id)
    values
        (?, ?, ?)

明显SQL少了一句。

inverse的默认值是false,代表不放弃外键维护权,配置值为true,代表放弃了外键的维护权。(让对方来维护)

Hibernate入门(十)inverse的更多相关文章

  1. Hibernate入门(十二)离线条件检索

    Hibernate——离线条件检索DetachedCriteria DetachedCriteria翻译为离线条件查询,因为它是可以脱离Session来使用的一种条件查询对象,我们都知道Criteri ...

  2. Hibernate入门5持久化对象关系和批量处理技术

    Hibernate入门5持久化对象关系和批量处理技术 20131128 代码下载 链接: http://pan.baidu.com/s/1Ccuup 密码: vqlv 前言: 前面学习了Hiberna ...

  3. Hibernate(十六):Hibernate二级缓存

    Hibernate缓存 缓存(Cache):计算机领域非常通用的概念.它介于应用程序和永久性数据存储源(如磁盘上的文件或者数据库)之间,起作用是降低应用程序直接读取永久性数据存储源的频率,从而提高应用 ...

  4. 走进JavaWeb技术世界13:Hibernate入门经典与注解式开发

    原文地址:Hibernate入门这一篇就够了 前言 本博文主要讲解介绍Hibernate框架,ORM的概念和Hibernate入门,相信你们看了就会使用Hibernate了! 什么是Hibernate ...

  5. 三大框架之hibernate入门

    hibernate入门   1.orm      hibernate是一个经典的开源的orm[数据访问中间件]框架           ORM( Object Relation Mapping)对象关 ...

  6. Hibernate入门案例及增删改查

    一.Hibernate入门案例剖析: ①创建实体类Student 并重写toString方法 public class Student { private Integer sid; private I ...

  7. Android入门(十二)SQLite事务、升级数据库

    原文链接:http://www.orlion.ga/610/ 一.事务 SQLite支持事务,看一下Android如何使用事务:比如 Book表中的数据都已经很老了,现在准备全部废弃掉替换成新数据,可 ...

  8. Hibernate入门案例 增删改

    一.Hibernate入门案例剖析: ①创建实体类Student 并重写toString方法 public class Student { private Integer sid; private I ...

  9. Hibernate入门6.Hibernate检索方式

    Hibernate入门6.Hibernate检索方式 20131128 代码下载 链接: http://pan.baidu.com/s/1Ccuup 密码: vqlv Hibernate的整体框架已经 ...

随机推荐

  1. 关于isNaN()函数的细节

    根据<JavaScript高级程序设计>的解释,NaN,即非数值(Not a Number),用于表示一个本来要返回数值的操作数未返回数值的情况,例如5/0就会得到NaN. 而因为NaN的 ...

  2. [转] Customizing OpenStack RBAC policies

    http://www.florentflament.com/blog/customizing-openstack-rbac-policies.html OpenStack uses a role ba ...

  3. 【.NET Core项目实战-统一认证平台】第五章 网关篇-自定义缓存Redis

    [.NET Core项目实战-统一认证平台]开篇及目录索引 上篇文章我们介绍了2种网关配置信息更新的方法和扩展Mysql存储,本篇我们将介绍如何使用Redis来实现网关的所有缓存功能,用到的文档及源码 ...

  4. redis & memcache 性能比较

    redis和memcache非常像的,都是key,value的方式,将数据存放内存中.最近在学习redis,在网上看了一些这方面的资料,有三种观点: redis读写内存比memcache快 memca ...

  5. bash 管理小脚本

    #!/bin/bash shell_user="root" shell_pass="1233" shell_port="22" shell_ ...

  6. HTML学习一_网页的基本结构及HTML简介

    HTML网页的基本结构 ```angular2html<!DOCTYPE html> 声明为 HTML5 文档<html> 元素是 HTML 页面的根元素<head> ...

  7. Kali学习笔记40:SQL手工注入(2)

    上一篇讲到可以通过注入得到数据库中所有的表信息 而SQL注入能不能做数据库之外的事情呢? 读取文件: ' union select null,load_file('/etc/passwd') -- 为 ...

  8. 使用JDOM解析xml文档

    一.使用JDOOM解析xml文档 准备工作 1.下载JDOM.jar 包 解析代码如下 import org.jdom2.Attribute; import org.jdom2.Document; i ...

  9. input01.sh: line 11: warning: here-document at line 4 delimited by end-of-file (wanted `EOF') input01.sh: line 12: syntax error: unexpected end of file

    写了个脚本用cat>>EOF报错如下: input01.sh: line 11: warning: here-document at line 4 delimited by end-of- ...

  10. Selenuim自动化测试模型

    本章内容: 概念介绍 自动化测试模型 一.概念 自动化测试库.框架.工具之间的区别: 库是由代码集合成的一个产品,供程序员调用,面向对象的代码组织形成的库叫类库,面向过程的代码组织形成的库叫函数库. ...