双向关联产生多余的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. 通过Weeman+Ettercap配合拿下路由器管理权限

    通过Weeman+Ettercap配合拿下路由器管理权限 本文转自>>>i春秋学院 本篇文章主要介绍如何在接入无线网络后如何拿到路由器的管理权限,至于如何得到路由器连接密码可以参考 ...

  2. 全栈开发工程师微信小程序-中(下)

    全栈开发工程师微信小程序-中(下) 微信小程序视图层 wxml用于描述页面的结构,wxss用于描述页面的样式,组件用于视图的基本组成单元. // 绑定数据 index.wxml <view> ...

  3. Kali学习笔记9:端口扫描详解(上)

    UDP端口扫描: 原理:回应ICMP不可达,代表端口关闭:没有回应,端口开启 建议了解应用层的UDP包头结构,构建对应的UDP数据包用来提高准确度 另外:所有的扫描都存在误判情况 我们用Scapy写个 ...

  4. GitHub 近 100,000 程序员“起义”:向“996”开炮!

    作者 | 伍杏玲 出品 | 程序人生(ID:coder_life) 平常CSDN推送关于程序员加班的文章时,很多程序员边吐槽边调侃地留言“比拼”:“我们也是996”.“007来报道”…… 可在简单的数 ...

  5. C语言中assert()断言函数的概念及用法

    断言函数的格式如下所示: void assert (int expression);如果参数expression等于零,一个错误消息将会写入到设备的标准错误集并且会调用abort函数,就会结束程序的执 ...

  6. 机器学习入门09 - 特征组合 (Feature Crosses)

    原文链接:https://developers.google.com/machine-learning/crash-course/feature-crosses/ 特征组合是指两个或多个特征相乘形成的 ...

  7. python学习笔记01-变量

    变量的作用: 1.保存信息  方便日后被调用 操作 2. 更改 代表描述性的意思 让人明白是什么意思 行业命名规则: 1.student_number 2.studentNumber 驼峰体 不要以大 ...

  8. freemarker变量自加

    [#assign i = 0][#list dateList as item][#assign i = i + 1]<li><input type="radio" ...

  9. Zabbix系列之五——监控TCP端口

    监控端口的几个主要Keys: net.tcp.listen[port] Checks if this port is in LISTEN state. 0 - it is not, 1 - it is ...

  10. mamp使用

    MAMP Pro软件是一款很好的在MAC下面运行的网站集成环境软件,功能强大,配置简单,十分便于本地调试,其由Apache+MySQL+PHP+动态DNS配置构成,PHP的版本可以动态切换到最新版.无 ...