Hibernate 检索策略

检索策略

1 概述
在查询数据库时,通常可以从两个方面提升程序的性能:
①节约内存空间
当应用程序需要读取Customer对象的数据并从数据库中将Customer对象加载到内存中,如果同时加载所有关联的Order对象的集合,但是又不使用,那么这些关联的Order对象就白白浪费了许多内存空间。
②少发送SQL语句
每发送一次SQL语句就需要获取一个数据库连接,与数据库进行一次完整的交互过程,而访问数据库往往是一个非常耗时的操作,应尽量减少访问数据库的次数。
2 类级别的检索策略:
load()方法的行为
①默认情况下加载对象时使用延迟检索策略,仅返回代理对象
②使用立即检索时,在方法执行时就加载全部数据

< class name ="Customer" table ="CUSTOMERS" lazy ="false">

3 访问n的一端时的检索策略
①默认情况
加载Customer的时候,不会自动立即加载关联的Order集合
②延迟加载
在Customer的set元素内设置lazy=”false”后就会在加载Customer的同时发送加载Order集合的SQL语句。注意:这里虽然使用了立即加载策略但是并没有合并成一条SQL语句,而是使用了两条SQL语句
延迟检索的SQL

Hibernate:
    select
        customer0_.CUST_ID as CUST_ID1_0_0_,
        customer0_.CUST_NAME as CUST_NAM2_0_0_
    from
        CUSTOMERS customer0_
    where
        customer0_.CUST_ID=?

在访问Order集合的数据之前

Hibernate:
    select
        orderset0_.CUST_ID_FK as CUST_ID_3_0_1_,
        orderset0_.ORDER_ID as ORDER_ID1_1_1_,
        orderset0_.ORDER_ID as ORDER_ID1_1_0_,
        orderset0_.ORDER_NAME as ORDER_NA2_1_0_,
        orderset0_.CUST_ID_FK as CUST_ID_3_1_0_
    from
        ORDERS orderset0_
    where
        orderset0_.CUST_ID_FK=?
ORDER01
ORDER02

在访问Order集合的数据之后

立即检索的SQL

Hibernate:
    select
        customer0_.CUST_ID as CUST_ID1_0_0_,
        customer0_.CUST_NAME as CUST_NAM2_0_0_
    from
        CUSTOMERS customer0_
    where
        customer0_.CUST_ID=?
Hibernate:
    select
        orderset0_.CUST_ID_FK as CUST_ID_3_0_1_,
        orderset0_.ORDER_ID as ORDER_ID1_1_1_,
        orderset0_.ORDER_ID as ORDER_ID1_1_0_,
        orderset0_.ORDER_NAME as ORDER_NA2_1_0_,
        orderset0_.CUST_ID_FK as CUST_ID_3_1_0_
    from
        ORDERS orderset0_
    where
        orderset0_.CUST_ID_FK=?

在访问Order集合的数据之前
ORDER02
ORDER01
在访问Order集合的数据之后

③增强的延迟加载
使用lazy属性的extra值表示进一步推迟将数据加载到内存的时机,例如:查询关联的集合的长度时,只发送一条count函数SQL语句

Hibernate:
    select
        customer0_.CUST_ID as CUST_ID1_0_0_,
        customer0_.CUST_NAME as CUST_NAM2_0_0_
    from
        CUSTOMERS customer0_
    where
        customer0_.CUST_ID=?
Hibernate:
    select
        count(ORDER_ID)
    from
        ORDERS
    where
        CUST_ID_FK =?
2

④batch-size
使用set元素的batch-size属性可以设置在内存中一次性初始化关联的Order集合的个数,减少发送SQL语句的次数。例如:内存中有5个Customer,batch-size=2
【注意:当lazy=时,batch-size设置无效】

Hibernate:
    select
        customer0_.CUST_ID as CUST_ID1_0_,
        customer0_.CUST_NAME as CUST_NAM2_0_
    from
        CUSTOMERS customer0_
customer的个数:5
Hibernate:
    select
        orderset0_.CUST_ID_FK as CUST_ID_3_0_1_,
        orderset0_.ORDER_ID as ORDER_ID1_1_1_,
        orderset0_.ORDER_ID as ORDER_ID1_1_0_,
        orderset0_.ORDER_NAME as ORDER_NA2_1_0_,
        orderset0_.CUST_ID_FK as CUST_ID_3_1_0_
    from
        ORDERS orderset0_
    where
        orderset0_.CUST_ID_FK in (
            ?, ?
        )

order集合长度:2
order集合长度:3

Hibernate:
    select
        orderset0_.CUST_ID_FK as CUST_ID_3_0_1_,
        orderset0_.ORDER_ID as ORDER_ID1_1_1_,
        orderset0_.ORDER_ID as ORDER_ID1_1_0_,
        orderset0_.ORDER_NAME as ORDER_NA2_1_0_,
        orderset0_.CUST_ID_FK as CUST_ID_3_1_0_
    from
        ORDERS orderset0_
    where
        orderset0_.CUST_ID_FK in (
            ?, ?
        )
order集合长度:1
order集合长度:1
Hibernate:
    select
        orderset0_.CUST_ID_FK as CUST_ID_3_0_1_,
        orderset0_.ORDER_ID as ORDER_ID1_1_1_,
        orderset0_.ORDER_ID as ORDER_ID1_1_0_,
        orderset0_.ORDER_NAME as ORDER_NA2_1_0_,
        orderset0_.CUST_ID_FK as CUST_ID_3_1_0_
    from
        ORDERS orderset0_
    where
        orderset0_.CUST_ID_FK=?
order集合长度:0

⑤set元素的fetch属性
[1]select:默认值
[2]subselect:忽略batch-size的设置,以子查询的方式加载全部的Order集合。

Hibernate:
    select
        customer0_.CUST_ID as CUST_ID1_0_,
        customer0_.CUST_NAME as CUST_NAM2_0_
    from
        CUSTOMERS customer0_
customer的个数:5
Hibernate:
    select
        orderset0_.CUST_ID_FK as CUST_ID_3_0_1_,
        orderset0_.ORDER_ID as ORDER_ID1_1_1_,
        orderset0_.ORDER_ID as ORDER_ID1_1_0_,
        orderset0_.ORDER_NAME as ORDER_NA2_1_0_,
        orderset0_.CUST_ID_FK as CUST_ID_3_1_0_
    from
        ORDERS orderset0_
    where
        orderset0_.CUST_ID_FK in (
            select
                customer0_.CUST_ID
            from
                CUSTOMERS customer0_
        )

order集合长度:2
order集合长度:3
order集合长度:1
order集合长度:1
order集合长度:0

[3]join时:会在加载Customer对象的时候,就“迫不及待”的查询关联的Order集合,这样的检索方式我们在Hibernate中称之为“迫切左外连接”。
注意:取值为join时,会忽略lazy属性的设置。但是fetch=join对HQL查询无效。
4 访问1的一端
①立即检索
在many-to-one元素中设置lazy=”false”
Tip:在many-to-one元素中lazy属性的可选值是:false、proxy、no-proxy,其中默认值是proxy。

Hibernate:
    select
        order0_.ORDER_ID as ORDER_ID1_1_0_,
        order0_.ORDER_NAME as ORDER_NA2_1_0_,
        order0_.CUST_ID_FK as CUST_ID_3_1_0_
    from
        ORDERS order0_
    where
        order0_.ORDER_ID=?
Hibernate:
    select
        customer0_.CUST_ID as CUST_ID1_0_0_,
        customer0_.CUST_NAME as CUST_NAM2_0_0_
    from
        CUSTOMERS customer0_
    where
        customer0_.CUST_ID=?
ORDER01
CUST01

②迫切左外连接
将fetch属性设置为join即可

Hibernate:
    select
        order0_.ORDER_ID as ORDER_ID1_1_1_,
        order0_.ORDER_NAME as ORDER_NA2_1_1_,
        order0_.CUST_ID_FK as CUST_ID_3_1_1_,
        customer1_.CUST_ID as CUST_ID1_0_0_,
        customer1_.CUST_NAME as CUST_NAM2_0_0_
    from
        ORDERS order0_
    left outer join
        CUSTOMERS customer1_
            on order0_.CUST_ID_FK=customer1_.CUST_ID
    where
        order0_.ORDER_ID=?
ORDER01
CUST01

③batch-size
当查询了一组Order,内存中存在多个Customer时,可以在Customer.hbm.xml文件的class元素中设置batch-size属性,决定加载一组Order集合时同时初始化Customer对象的个数。例如:内存中有4个Customer需要初始化,batch-size设置为3时:

Hibernate:
    select
        order0_.ORDER_ID as ORDER_ID1_1_,
        order0_.ORDER_NAME as ORDER_NA2_1_,
        order0_.CUST_ID_FK as CUST_ID_3_1_
    from
        ORDERS order0_
Hibernate:
    select
        customer0_.CUST_ID as CUST_ID1_0_0_,
        customer0_.CUST_NAME as CUST_NAM2_0_0_
    from
        CUSTOMERS customer0_
    where
        customer0_.CUST_ID in (
            ?, ?, ?
        )
CUST01
CUST01
CUST02
CUST02
CUST02
CUST03
Hibernate:
    select
        customer0_.CUST_ID as CUST_ID1_0_0_,
        customer0_.CUST_NAME as CUST_NAM2_0_0_
    from
        CUSTOMERS customer0_
    where
        customer0_.CUST_ID=?
CUST04
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值