hibernate数据加载方式

在传统的JDBC操作里,通常通过sql语句查询加载所需要的数据,当sql提交之后,这些数据也就被读取待用了,而在hibernate里,我们拥有了更多的数据加载的方式。以实现不同种的需求。

hibernate支持以下四种数据加载方式:

1、及时加载(Immediate Loading)--实体加载后,立即加载其关联数据。

2、延迟加载(Lazy Loading)--实体加载后,关联数据第一次被需要时,即访问然后加载。

3、预先加载(Eager Loading)--预先加载时,实体及其关联同时读取,于及时加载类似,但是通过一条sql(基于外连接查询)

4、批量加载(Batch Loading)--相对于及时和延迟加载,采用批量方式,可以进行性能上的优化。

一、及时加载

还是引入上篇中的User表和Address表,即一个用户可有多个住址。其配置中部分关联关系如下:

Xml代码
  1. <set
  2. name="address"
  3. table="Address"
  4. inverse="true"
  5. cascade="none"
  6. sort="unsorted"
  7. lazy="false"
  8. >
  9. <keycolumn="user_id"/>
  10. <one-to-manyclass="com.entity.Address"/>
  11. </set>

此时,再去做一个查询,代码如下:

Java代码
  1. Stringhql="fromUserwherename='Erica'";
  2. Listlist=session.createQuery(hql).list();
  3. syso("queryfinished");
  4. Iteratorit=list.iterator();
  5. while(it.hasNext()){
  6. Useruesr=(User)it.next();
  7. syso(user.getName());
  8. syso(user.getAddresses().size());
  9. }

在设置过show_sql后,控制台打印如下信息:

Java代码
  1. Hibernate:select......fromUseruserwhere(name='Erica')
  2. Hibernate:select......fromAddressaddrwhereaddr.user_id=?
  3. queryfinished
  4. Erica
  5. 2

从中我们可以得出,在执行find的时候,hibernate链接调用了2条sql语句,分别完成了对User和Address对象的加载。这就是及时加载的原理,当关联主体加载时(此处则我们的User对象),hibernate会立即自动读取其关联数据并完成关联属性的填充。

二、延时加载

延时加载就是对应上面及时加载所产生的,当我们不需要关联表的数据的时候,我们不需要查询,需要的时候,再发送语句,这样就避免了过多的性能的消耗。

将上面的部分配置的lazy属性改掉(hibernate3中,lazy属性默认为true,即默认启用延迟加载),即代码如下:

Xml代码
  1. <set
  2. name="address"
  3. table="Address"
  4. inverse="true"
  5. cascade="none"
  6. sort="unsorted"
  7. lazy="true"
  8. >
  9. <keycolumn="user_id"/>
  10. <one-to-manyclass="com.entity.Address"/>
  11. </set>

再次运行查询代码,我们发现控制台打印了如下的show_sql信息:

Java代码
  1. hibernate:select.....fromUseruserwhere(name='Erica')
  2. queryfinished
  3. Erica
  4. hibernate:select.....fromAddressaddrwhereaddr.user_id=?
  5. 2

与上面的不同的是,当代码运行到syso(user.getName());时,hibernate只有一条语句,而然在打印地址的个数的时候,激发了第二天sql语句去查询size()的大小。这就是他的特点,当真正需要关联表的数据的时候才会去做读取操作,从而提高性能。

三、预先加载

预先加载是通过outer join完成关联数据的加载,也是通过一条sql语句完成对实体以及其关联数据的读取操作,相对应即时加载的两条或多条,无疑提高了性能,但是一般只适用于一对一的关系。对于大部分的集合类型,还是推荐使用延迟加载的模式。一般而言,outer join可以提高处理的效率,但是对于关联关系复杂的,如多层关联,hibernate会生成非常复杂的sql语句,此时,我们应该根据实际情况,判断它的实用性,同时,也可以通过设置全局变量(hibernate.max_fetch_depth)限定outer-join的关联层次,一般5层比较合适。

四、批量加载

顾名思义,就是通过批量提交多个限定条件,一次完成多个数据读取,如对于下面的sql请求:select from User where id=1; select from User where id=2经过整合后变为,select from User where id=1 or id=2。如果使用了这种方式,hibernate在进行数据操作前,会自动在当前session中寻找,是否有其他同类型的待加载的数据,如果有,则将其合并在当前的select 语句中一起提交。

在实体的配置中,我们可以在class节点下,通过设置batch-size打开批量加载机制,并限定每次批量加载的数量,代码如下:

Xml代码
  1. <classname="User"table="Uesr"batch-size="5">
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值