`
baobeituping
  • 浏览: 1071470 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Hibernate 批量加载(立即、延迟)

阅读更多

一、批量立即加载

以上面的例子为例:

Team对学生采取的是立即加载

 

客户端:

Session session = SessionUtil.getSession();
  Transaction tran = session.beginTransaction();
  Query query = session.createQuery("from Team");
  List list = query.list();
  tran.commit();
  session.close();

 

数据库中有5个TEAM,对应每个TEAM都有学生,那么打印语句:

Hibernate: select team0_.ID as ID0_, team0_.Name as Name0_ from test.team team0_

Hibernate: select students0_.teamID as teamID3_, students0_.ID as ID3_, students0_.ID as ID1_2_, students0_.Name as Name1_2_, students0_.TeamID as TeamID1_2_, team1_.ID as ID0_0_, team1_.Name as Name0_0_, card2_.ID as ID2_1_, card2_.StudentID as StudentID2_1_, card2_.Name as Name2_1_ from test.student students0_ left outer join test.team team1_ on students0_.TeamID=team1_.ID left outer join test.card card2_ on students0_.ID=card2_.ID where students0_.teamID=?

Hibernate: select students0_.teamID as teamID3_, students0_.ID as ID3_, students0_.ID as ID1_2_, students0_.Name as Name1_2_, students0_.TeamID as TeamID1_2_, team1_.ID as ID0_0_, team1_.Name as Name0_0_, card2_.ID as ID2_1_, card2_.StudentID as StudentID2_1_, card2_.Name as Name2_1_ from test.student students0_ left outer join test.team team1_ on students0_.TeamID=team1_.ID left outer join test.card card2_ on students0_.ID=card2_.ID where students0_.teamID=?

Hibernate: select students0_.teamID as teamID3_, students0_.ID as ID3_, students0_.ID as ID1_2_, students0_.Name as Name1_2_, students0_.TeamID as TeamID1_2_, team1_.ID as ID0_0_, team1_.Name as Name0_0_, card2_.ID as ID2_1_, card2_.StudentID as StudentID2_1_, card2_.Name as Name2_1_ from test.student students0_ left outer join test.team team1_ on students0_.TeamID=team1_.ID left outer join test.card card2_ on students0_.ID=card2_.ID where students0_.teamID=?

Hibernate: select students0_.teamID as teamID3_, students0_.ID as ID3_, students0_.ID as ID1_2_, students0_.Name as Name1_2_, students0_.TeamID as TeamID1_2_, team1_.ID as ID0_0_, team1_.Name as Name0_0_, card2_.ID as ID2_1_, card2_.StudentID as StudentID2_1_, card2_.Name as Name2_1_ from test.student students0_ left outer join test.team team1_ on students0_.TeamID=team1_.ID left outer join test.card card2_ on students0_.ID=card2_.ID where students0_.teamID=?

Hibernate: select students0_.teamID as teamID3_, students0_.ID as ID3_, students0_.ID as ID1_2_, students0_.Name as Name1_2_, students0_.TeamID as TeamID1_2_, team1_.ID as ID0_0_, team1_.Name as Name0_0_, card2_.ID as ID2_1_, card2_.StudentID as StudentID2_1_, card2_.Name as Name2_1_ from test.student students0_ left outer join test.team team1_ on students0_.TeamID=team1_.ID left outer join test.card card2_ on students0_.ID=card2_.ID where students0_.teamID=?

对于以上语句,首先查询TEAM的值,因为采取的是立即加载,对有多少个班级就发出多少条SQL语句。如果有100个班级,那么就会发出100条的查询语句,性能可以想象!!所以一定要改变这种情况。

我们可以在一对多的一的这端的:

 <set name="students" inverse="true" cascade="all" lazy="false" batch-size="2">
            <key column="teamID"></key>
            <one-to-many class="com.vo.Student"></one-to-many>
        </set>

 

设置batch-size的值,首先来看看采用这种策略以后的语句:

Hibernate: select team0_.ID as ID0_, team0_.Name as Name0_ from test.team team0_

Hibernate: select students0_.teamID as teamID3_, students0_.ID as ID3_, students0_.ID as ID1_2_, students0_.Name as Name1_2_, students0_.TeamID as TeamID1_2_, team1_.ID as ID0_0_, team1_.Name as Name0_0_, card2_.ID as ID2_1_, card2_.StudentID as StudentID2_1_, card2_.Name as Name2_1_ from test.student students0_ left outer join test.team team1_ on students0_.TeamID=team1_.ID left outer join test.card card2_ on students0_.ID=card2_.ID where students0_.teamID in (?, ?)

Hibernate: select students0_.teamID as teamID3_, students0_.ID as ID3_, students0_.ID as ID1_2_, students0_.Name as Name1_2_, students0_.TeamID as TeamID1_2_, team1_.ID as ID0_0_, team1_.Name as Name0_0_, card2_.ID as ID2_1_, card2_.StudentID as StudentID2_1_, card2_.Name as Name2_1_ from test.student students0_ left outer join test.team team1_ on students0_.TeamID=team1_.ID left outer join test.card card2_ on students0_.ID=card2_.ID where students0_.teamID in (?, ?)

Hibernate: select students0_.teamID as teamID3_, students0_.ID as ID3_, students0_.ID as ID1_2_, students0_.Name as Name1_2_, students0_.TeamID as TeamID1_2_, team1_.ID as ID0_0_, team1_.Name as Name0_0_, card2_.ID as ID2_1_, card2_.StudentID as StudentID2_1_, card2_.Name as Name2_1_ from test.student students0_ left outer join test.team team1_ on students0_.TeamID=team1_.ID left outer join test.card card2_ on students0_.ID=card2_.ID where students0_.teamID=?

 

发现采取的查询策略改变了,SQL的条件是where id in(?,?)

因为设置了批量加载为2,假如有100个班级,那么只要加载50次,如果设置为3,那么就是加载100/3=33次,剩余的一次采用立即加载的方式,所以这也是为什么上面例子的最后一句是立即加载的原因。

 

没有用batch_size的SQL采用ID=?的形式

采用batch_size的SQL采用ID in()的形式。

这就是为什么SQL语句会减少的原因。

二、批量延迟加载

首先在TEAM的配置文件中更改对学生的加载策略为延迟加载。并且设置批量加载为2.

客户端:

Session session = SessionUtil.getSession();
  Transaction tran = session.beginTransaction();
  Query query = session.createQuery("from Team");
  List list = query.list();
  Team team = (Team)list.get(0);
  System.out.println(team.getName()+" 学生数量:"+team.getStudents().size());
  
   team = (Team)list.get(2);
  System.out.println(team.getName()+" 学生数量:"+team.getStudents().size());
  
   team = (Team)list.get(4);
  System.out.println(team.getName()+" 学生数量:"+team.getStudents().size());
  tran.commit();
  session.close();

 

打印语句:

Hibernate: select team0_.ID as ID0_, team0_.Name as Name0_ from test.team team0_

Hibernate: select students0_.teamID as teamID3_, students0_.ID as ID3_, students0_.ID as ID1_2_, students0_.Name as Name1_2_, students0_.TeamID as TeamID1_2_, team1_.ID as ID0_0_, team1_.Name as Name0_0_, card2_.ID as ID2_1_, card2_.StudentID as StudentID2_1_, card2_.Name as Name2_1_ from test.student students0_ left outer join test.team team1_ on students0_.TeamID=team1_.ID left outer join test.card card2_ on students0_.ID=card2_.ID where students0_.teamID in (?, ?)

二中 学生数量:2

一职 学生数量:1

Hibernate: select students0_.teamID as teamID3_, students0_.ID as ID3_, students0_.ID as ID1_2_, students0_.Name as Name1_2_, students0_.TeamID as TeamID1_2_, team1_.ID as ID0_0_, team1_.Name as Name0_0_, card2_.ID as ID2_1_, card2_.StudentID as StudentID2_1_, card2_.Name as Name2_1_ from test.student students0_ left outer join test.team team1_ on students0_.TeamID=team1_.ID left outer join test.card card2_ on students0_.ID=card2_.ID where students0_.teamID in (?, ?)

十一中 学生数量:1

 

第1条的解释:首先去查询TEAM的集合对象。

第2条的解释:因为采用的是延迟加载,只有当用到对象的属性的时候才发送SQL去数据库取值,所以发出第2条语句,因为设置了批量加载为2,所以发出的该条SQL语句将把班级序号为1和2的班级都查出来,所以当我们去取得班级为2的时候就不再发送查询语句了。

第3条SQL解释:因为打印的是第4个班级,所以要再发送一条查询语句。

 

对于批量加载也不是设置的batch_size越大越好。

例如,对于A-B(有5个B对象),我们设置的batch_size=5,当我们只要查询中间的一条数据,系统会发出5条SQL语句去查询。反而增加了系统的开销。

 

分享到:
评论

相关推荐

    Hibernate集合属性的延迟加载.doc

    此外,还可以通过设置 `&lt;set&gt;` 标签的 `fetch` 属性来控制查询策略,比如使用 `fetch="subselect"` 来预加载集合的大小,或者使用 `batch-size` 来批量加载一定数量的关联记录,进一步优化性能。 总的来说,...

    hibernate延迟加载技术详细解

    通过设置 `hibernate.default_batch_fetch_size` 参数来指定批量加载的大小。 - 适用于关联数据量大且需要频繁访问的情况,可以有效减少数据库交互次数。 5. **Immediate Fetching**: - 即使设置了懒加载,但...

    Hibernate之数据加载方式

    3. **批量加载(Bulk Operations)**:`Session.loadAll()`可以一次性加载多个对象,适用于批量处理场景。 4. **分页加载(Pagination)**:通过`Query.setFirstResult()`和`Query.setMaxResults()`实现分页加载,...

    hibernate抓取策略和懒加载案例

    3. Batch Fetching(批量加载):通过一次查询获取多个关联对象,减少数据库的IO操作,提高效率。 4. Subselect Fetching(子查询加载):在主查询外使用子查询来获取关联对象,适用于关联数据较小的情况。 5. ...

    C#Hibernate数据库海量读写快速存储

    3. 预加载数据:在客户端预加载部分常用数据,减少网络请求。 4. 调整服务器配置:根据业务需求调整服务器硬件资源,如增加内存、提升网络带宽等。 总结来说,结合C#、Hibernate和SQL Server,开发者可以构建高效的...

    Hibernate-extensions 完整安装包

    1. 延迟加载:Hibernate-Extensions支持更细粒度的延迟加载控制,例如属性级别的延迟加载,这在处理大数据量时尤其有用,可以显著减少内存消耗。 2. 实体监听器:通过实现EntityListener接口,开发者可以在特定的...

    HIBERNATE检索策略

    这是HIBERNATE默认的抓取策略,当一个实体被加载时,与之关联的实体或集合并不会立即加载,而是采用延迟加载(Lazy Loading)的方式。当第一次访问关联实体或集合时,HIBERNATE会额外发送一条SELECT语句来抓取数据,...

    hibernate 中文参考文档

    - **批量加载与延迟加载**:合理使用批量加载和延迟加载策略,可以有效减少数据库交互次数,提升应用性能。 ### 高级特性 - **多租户支持**:Hibernate提供了多租户模式的支持,允许在单一的应用程序中管理多个...

    Hibernate学习笔记和资料

    hibernate中一对一,一对多,多对多关系的配置,延迟加载,cascade,inverse hibernate查询方式概述,HQL查询,QBC查询,分页,结果集封装方式 ,高级查询 查询的优化,一级缓存,二级缓存,批量查询,注解方式

    Hibernate4.0,Hibernate5.2,Hibernate5.6 jar包

    这个版本进一步提升了性能和稳定性,对JPA 2.1规范进行了兼容,增加了对延迟加载和实体图形的深度遍历的支持。它还引入了对Java 8特性的支持,比如日期和时间API的改进。在多线程和并发处理方面也做了优化,提供了更...

    hibernate教程打包下载,史上最全的HIBERNATE

    10. **性能优化**:教程可能涵盖如何优化Hibernate,例如批量操作、延迟加载、缓存策略调整、避免N+1查询问题等。 11. **实例分析**:通过实际项目案例,演示如何在Web应用(如Spring Boot)中整合Hibernate,解决...

    hibernate面试题2

    - Hibernate通过延迟加载策略,只在实际访问数据时才加载,节省内存,提高性能。 7. **类之间的关系映射**: - 通过配置文件如`one-to-many`、`many-to-one`、`many-to-many`等映射关系,实现类与类的关联。 8. ...

    Hibernate框架jia包

    -延迟加载(Lazy Loading):只在需要时加载关联对象,避免数据冗余。 8. **HQL和Criteria API**: HQL是面向对象的查询语言,类似于SQL但更接近Java。Criteria API则提供了一个程序化的查询方式,可以在运行时...

    如何提高hibernate性能

    当需要抓取延迟加载的集合或单值代理时,Hibernate会使用子查询一次性加载所有实例。这种方法避免了破碎的加载,提高了效率。 6. **延迟属性抓取(Lazy Property Fetching)**: Hibernate 3支持对单独属性进行...

    Hibernate5实例程序

    优化包括合理设置缓存策略、避免N+1查询问题、批量操作、延迟加载等。理解并合理运用这些技巧,可以显著提升Hibernate应用的性能。 通过《Hibernate5实例程序》中的代码示例,读者可以亲手实践上述各个知识点,...

    jsp中Hibernate资料

    为了提高数据访问效率,Hibernate引入了一系列性能优化措施,如二级缓存、批量加载和延迟加载。其中,批量加载和延迟加载尤其有助于减少数据库交互次数,提高应用响应速度。 ### 正向工程与反向工程 在Hibernate中...

    hibernate代码

    10. **延迟加载(Lazy Loading)**:Hibernate支持关联对象的延迟加载,只有在真正需要时才会加载关联的数据,避免了不必要的数据库查询。 11. **事件监听器**:通过实现Hibernate的事件监听接口,可以对特定的持久...

    Hibernate提升性能Hibernate提升性能

    因此,平衡延迟加载和立即加载的使用,结合合适的批量抓取策略,是提高Hibernate性能的关键。 总的来说,理解并熟练运用Hibernate的抓取策略,能够帮助开发者创建更高效的数据访问层,降低系统开销,从而提升整体...

    hibernate 3.2.2

    1. 懒加载:默认情况下,关联的对象不会在加载实体时一起加载,而是在需要时通过代理对象延迟加载,减少内存占用。 2. 级联操作:设置级联属性可以在操作主对象时自动处理其关联对象,如`CascadeType.ALL`表示对所有...

    Hibernate 中文参考文档

    为了提高性能,Hibernate提供了批量插入、更新和删除功能,以及延迟加载、批处理等优化策略。合理使用这些特性可以显著提升应用性能。 综上所述,Hibernate中文参考文档详尽地阐述了如何使用Hibernate进行数据持久...

Global site tag (gtag.js) - Google Analytics