zoukankan      html  css  js  c++  java
  • Hibernate入门(十)inverse

    双向关联产生多余的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,代表放弃了外键的维护权。(让对方来维护)

  • 相关阅读:
    006_tcpdump专题
    002_阿里监控平台的“打怪升级”之路
    001_谈阿里核心业务监控平台SunFire的技术架构
    001_前端面试集合
    007_zkCli.sh
    007_Chrome的Waterfall详解
    021_supervise进行管理利器
    028_shell脚本递归求值
    MySQL -- 在磁盘爆满后复制的状态
    MySQL -- 内存使用监控详解
  • 原文地址:https://www.cnblogs.com/deepSleeping/p/9979245.html
Copyright © 2011-2022 走看看