hibernate检索策略

1.1概念

即在建立关联关系的情况下,在加载当时对象时对象时,对关联对象的检索策略。合理设置关联关系,可以提高软件的效率。

1.2立即检索策略



实现方法:将<set>元素的lazy设置为false

检索方式:立即初始化与当前对相关联的对象

优点:即使当前状态为游离状态,也可以方便地从当前对象导航到与之关联的对象

缺点:执行太多的select语句,增加访问数据库的次数,还可能加载程序中不需要的对象,既浪费时间又浪费缓存空间

优先考虑使用的场合:

(1) 在程序中需要立即访问关联对象

(2) 使用二级缓存

注意事项:

(1)在一对多关联中应该尽量避免立即检索,特殊情况除外

(2)在多对一关联中应根据实际情况决定采用何种检索策略

1.3一对多的立即检索

Hibernate默认情况下,一对多关联采用用户演示检索策略。因为通常情况下,在程序中不需在立即访问关联对象,如果这种情况下采用立即检索,无疑会执行多余的select语句,加长了加载时间,占用了缓存空间。如果在特殊情况下可以设置为一对多的立即检索。

//一对多的检索测试
@Test
public void fun3(){
    Session currentSession = HibernateUtil.getCurrentSession();
    Transaction transaction = currentSession.beginTransaction();
    List<Employee> list = currentSession.createQuery("from Employee").list();
    for (int i = 0; i <list.size() ; i++) {
        System.out.println(list);
    }
    transaction.commit();
    HibernateUtil.close(currentSession);
}

1.4延时缓存

实现方法:将<set>元素的lazy设置为true,lazy的默认值为true

检索方式:不立即初始化与当前的对相关联的对象。而是为关联对象创建一个代理对象,该对象只有OID被初始化,只有该代理对象的其他属性被请求时,对初始化该代理对象。

优点:由程序动态控制对象的加载,可以避免执行不必要的select语句加载不需要的对象,可以节省时间和缓存

缺点:当访问处于游离状态的对象时,必须保证关键对象已经被初始化。

优先考虑使用场景:

(1)一对多或多对多关联

(2)在程序不需要立即访问与之关联的对象


1.5类级别检索

get:立即检索。get方法一执行,立即查询所有字段的数据。

load:延迟检索。默认情况,load方法执行后,如果只使用OID的值不进行查询,如果要使用其他属性值将查询 。 Customer.hbm.xml <class  lazy="true |false">

              lazy默认值true,表示延迟检索,如果设置false表示立即检索。

1. get/load
get: 立即查询数据库,将数据初始化
load:  hbm文件中,class元素的lazy属性决定类级别load方法的加载策略
true:先返回一个代理对象.使用代理对象的属性时,才去查询数据库.
false: 与get一致,会立即加载数据


一对多或多对多

  容器<set> 提供两个属性:fetch、lazy

       fetch:确定使用sql格式

       lazy:关联对象是否延迟。

  fetch:join、select、subselect

       join:底层使用迫切左外连接

       select:使用多个select语句(默认值)

       subselect:使用子查询

 lazy:false、true、extra

       false:立即

       true:延迟(默认值)

       extra:极其懒惰

fetch="select"

  当前对象 和 关联对象 使用多条select语句查询。

  lazy="false" , 立即,先查询客户select,立即查询订单select

  lazy="true",延迟,先查询客户select,需要订单时,再查询订单select

  lazy="extra",极其懒惰(延迟),先查询客户select, 如果只需要订单数,使用聚合函数(不查询详情)

关联级别加载策略
在查询有关联关系的数据时,加载一方的数据是否需要将另一方立即查询出.
默认: 与我关联的数据,在使用时才会加载.
集合(一对多):
set 
lazy: 是否对set数据使用懒加载
true:(默认值) 对集合使用才加载
false: 集合将会被立即加载
extra: 极其懒惰,如果使用集合时,之调用size方法查询数量, Hibernate会发送count语句,只查询数量.不加载集合内数据.
fetch : 决定加载集合使用的sql语句种类
select: (默认值) 普通select查询
join: 表链接语句查询集合数据
subselect: 使用子查询 一次加载多个Customer的订单数据

1.6批量检索策略

在映入一对多关联中,还可以通过Hibernate提供的批量检索功能,实现批量检索数据,减少执行select语句的条数,从而减少访问数据库的次数,提升软件的性能。

批量检索功能的实现要和立即检索或延时间所联合使用。通过配置<set>元素的batch-size属性实现,在默认情况下值为1,经过大量的实践证明:batch-size的合理取值应该在2到10之间,如果值过大,复杂的sql语句会影响加载的速度,如果采用延时加载。会降低延时检索的意义。

在默认情况下,初始化每个当前对象都要执行一条select语句,如果设置为2,执行一条select语句则可以初始化包含当前对象在内的两个对象的所有关联对象。

1.7迫切左外连接检索策略

迫切左外连接检索策略与立即检所实现的功能相同,区别在于前者只需要执行一条select语句,而后者需执行多条select语句,相对而言减少了访问数据库的次数,不过单次访问时间上有所增加,以为select语句的复杂度增加了。

实现方法:将<set>元素的fetch设置为join

String hql2="from Employee e left join fetch e.enterprise";

检索方式:立即初始化与当前对相关联的对象,该检索只对session的load()和get()方法有效。当同时使用延时检索和迫切左外连接检索时,后者将覆盖前者。

优点:无论当前对象处于持久还是游离状态,都可以关联到与之关联的对象,并且比立即检索策略执行的sql语句少,只执行一条sql语句。

缺点:可能加载当前对象不需要的对象,增加缓存的使用率,复杂的select语句会影响检索功能

使用场景:

(1)一对一或多对一关联

(2)在程序中需要立即访问与之关联的对象

(3)具有良好的数据库表结构

实现迫切左外连接检索有两种方式:

(1)通过配置文件实现

(2)通过HQL语句实现

1.8通过配置文件实现

在配置文件中配置迫切左外连接检索只对session的get()和load()方法有效。迫切左外连接检索策略配置映射文件的fetch属性来实现,在<many-to-one><one-to-many>和<set>元素中拥有该属性。


  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

double_lifly

点喜欢就是最好的打赏!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值