`

Hibernate的fetch

 
阅读更多

hibernate抓取策略fetch详解
一、hibernate抓取策略(单端代理的批量抓取fetch=select(默认)/join)
测试用例:

Student student = (Student) session.get(Student.class, 43);
			
System.out.println("student name  "+student.getName());
			
System.out.println("class name    "+student.getClasses().getName());

 

1)保持默认,同fetch="select",如:

<many-to-one name="classes" column="classesid" fetch="select"/>

 

fetch="select"会另外发送一条select语句抓取当前对象关联实体或集合


执行结果:2条语句

Hibernate: select student0_.id as id1_0_, student0_.name as name1_0_, student0_.class_id as class3_1_0_ from student student0_ where student0_.id=?

student name  ccc 

Hibernate: select myclass0_.id as id0_0_, myclass0_.name as name0_0_ from class myclass0_ where myclass0_.id=?

class name    09002

 
2)设置fetch="join",如:

<many-to-one name="classes" column="classesid" fetch="join"/>

 

fetch="join",hibernate会通过select语句使用外连接来加载其关联实体或集合,此时lazy会失效。

执行结果:一条join语句

Hibernate: select student0_.id as id1_1_, student0_.name as name1_1_, student0_.class_id as class3_1_1_, myclass1_.id as id0_0_, myclass1_.name as name0_0_ from student student0_ inner join class myclass1_ on student0_.class_id=myclass1_.id where student0_.id=?

student name  ccc
class name    09002

 二、hibernate抓取策略(集合代理的批量抓取,fetch=select(默认)/join/subselect)

测试用例:

MyClass class1 = (MyClass) session.load(MyClass.class, 28);
			
         System.out.println("班级名:" + class1.getName());

         Set<Student> students = class1.getStudents();
         System.out.println("班级人数:" + students.size());
			
                   if (students != null && !students.isEmpty()) {
				
                         Iterator<Student> iterator = students.iterator();
	       System.out.print("学生姓名:");
				
                          while (iterator.hasNext()) {
					
                                               Student student = iterator.next();
					
                                                System.out.println(student.getName());
				}
			}

 

1)保持默认,同fetch="select",如:

<set name="students" inverse="true" fetch="select">

 

fetch="select",另外发送一条select语句抓取当前对象关联实体或集合

测试结果:2条独立的查询语句

Hibernate: select myclass0_.id as id0_0_, myclass0_.name as name0_0_ from class myclass0_ where myclass0_.id=?
班级名:09002

Hibernate: select students0_.class_id as class3_0_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.class_id as class3_1_0_ from student students0_ where students0_.class_id=?
班级人数:3
学生姓名:ccc
bbb
aaa

 

(2)设置fetch="join",如:

<set name="students" inverse="true" fetch="join">

 

fetch="join",hibernate会通过select语句使用外连接来加载其关联实体或集合,此时lazy会失效

测试结果:1条独立的join查询语句

Hibernate: select myclass0_.id as id0_1_, myclass0_.name as name0_1_, students1_.class_id as class3_0_3_, students1_.id as id3_, students1_.id as id1_0_, students1_.name as name1_0_, students1_.class_id as class3_1_0_ from class myclass0_ left outer join student students1_ on myclass0_.id=students1_.class_id where myclass0_.id=?
班级名:09002
班级人数:3
学生姓名:aaa
ccc
bbb

 (3)设置fetch="subselect",如:用在查询语句中

<set name="students" inverse="true" fetch="subselect">

 

fetch="subselect",另外发送一条select语句抓取在前面查询到的所有实体对象的关联集合

测试用例:

List<MyClass> classes = session.createQuery("from MyClass where id in (27,28,29)").list();
			
            Iterator<MyClass> iterator1 = classes.iterator();
			
              while(iterator1.hasNext()){
				
                 MyClass class1 = iterator1.next();
				
                 System.out.println("班级名:" + class1.getName());

				
                  Set<Student> students = class1.getStudents();
				
                  System.out.println("班级人数:" + students.size());
				
                   if (students != null && !students.isEmpty()) {
					
                         Iterator<Student> iterator = students.iterator();
					
                         System.out.print("学生姓名:");
					
                         while (iterator.hasNext()) {
						
                              Student student = iterator.next();
                              System.out.println(student.getName());
					}
				}
				
			}

 

 

当不设fetch="subselect" ,即::<set name="students" inverse="true">

结果如下:执行了4条查询语句,其中有3条关联查询语句。

Hibernate: select myclass0_.id as id0_, myclass0_.name as name0_ from class myclass0_ where myclass0_.id in (27 , 28 , 29)
班级名:09002
Hibernate: select students0_.class_id as class3_0_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.class_id as class3_1_0_ from student students0_ where students0_.class_id=?
班级人数:0

班级名:09003
Hibernate: select students0_.class_id as class3_0_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.class_id as class3_1_0_ from student students0_ where students0_.class_id=?
班级人数:3
学生姓名:ccc
aaa
bbb

班级名:09004
Hibernate: select students0_.class_id as class3_0_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.class_id as class3_1_0_ from student students0_ where students0_.class_id=?
班级人数:3
学生姓名:ccc
bbb
aaa

 

当设fetch="subselect" ,即:<set name="students" inverse="true" fetch="subselect">,结果如下:

执行了2条查询语句,其中有1条子查询语句(嵌套子查询)

Hibernate: select myclass0_.id as id0_, myclass0_.name as name0_ from class myclass0_ where myclass0_.id in (27 , 28 , 29)
班级名:09002
Hibernate: select students0_.class_id as class3_0_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.class_id as class3_1_0_ from student students0_ where students0_.class_id in (select myclass0_.id from class myclass0_ where myclass0_.id in (27 , 28 , 29))
班级人数:0
班级名:09003
班级人数:3
学生姓名:ccc
aaa
bbb
班级名:09004
班级人数:3
学生姓名:bbb
ccc
aaa

 

总结:

hibernate抓取策略(单端代理的批量抓取)

保持默认,同fetch="select",如:
<many-to-one name="classes" column="classesid" fetch="select"/>

fetch="select",另外发送一条select语句抓取当前对象关联实体或集合

 

2.hibernate抓取策略(单端代理的批量抓取)

设置fetch="join",如:
<many-to-one name="classes" column="classesid" fetch="join"/>

fetch="join",hibernate会通过select语句使用外连接来加载其关联实体或集合

此时lazy会失效

 

3.hibernate抓取策略(集合代理的批量抓取)

保持默认,同fetch="select",如:
<set name="students" inverse="true" cascade="all" fetch="select">

fetch="select",另外发送一条select语句抓取当前对象关联实体或集合

 

4.hibernate抓取策略(集合代理的批量抓取)

设置fetch="join",如:
<set name="students" inverse="true" cascade="all" fetch="join">

fetch="join",hibernate会通过select语句使用外连接来加载其关联实体或集合

此时lazy会失效

 

5.hibernate抓取策略(集合代理的批量抓取)

设置fetch="subselect",如:
<set name="students" inverse="true" cascade="all" fetch="subselect">

fetch="subselect",另外发送一条select语句抓取在前面查询到的所有实体对象的关联集合

 

6.hibernate抓取策略,,batch-szie在<class>上的应用

batch-size属性,可以批量加载实体类,参见:Classes.hbm.xml
<class name="Classes" table="t_classes" batch-size="3">

当查classes对象时发出9条hql语句配置过后batch-size=3后会之发9/3=3条hql语句,提高性能

 

7.hibernate抓取策略,batch-szie在集合上的应用


batch-size属性,可以批量加载实体类,参见:Classes.hbm.xml
<set name="students" inverse="true" cascade="all" batch-size="5">

当查students对象时发出10条hql语句配置过后batch-size=5后会之发10/5=2条hql语句,提高性能

 

 

总体上分析:默认是fetch="select" 当配置fetch="join"时直接查询包含的对象或者集合lazy失效。

分享到:
评论

相关推荐

    Hibernate Fetch 的作用

    在深入探讨Hibernate Fetch的作用之前,我们首先需要理解Hibernate框架本身以及其在持久化领域的重要性。Hibernate是一个开源的对象关系映射(ORM)框架,用于Java应用,它提供了将数据库记录映射到对象的方法,使得...

    Hibernate 经典例子全

    在`hibernate_fetch_1`示例中,我们了解到Hibernate的加载策略,包括Eager Fetching(即时加载)和Lazy Fetching(延迟加载)。即时加载会在查询时一起加载关联的对象,而延迟加载则只在真正需要时才执行数据库查询...

    hibernate

    根据提供的文件信息,我们可以深入探讨Hibernate框架中的几个关键概念,特别是`fetch`, `lazy`, `cascade`, 和 `inverse`关键字的使用与理解。这四个概念在处理对象关系映射(ORM)时非常重要,尤其是在Java环境下...

    hibernate 中 fetch=FetchType.LAZY 懒加载失败处理方法

    hibernate 中 fetch=FetchType.LAZY 懒加载失败处理方法 Hibernate 中 fetch=FetchType.LAZY 懒加载失败处理方法是 Hibernate 框架中的一种常见问题。当我们在 Hibernate 中使用懒加载特性时,可能会遇到 ...

    让hibernate输出sql语句参数配置.doc

    hibernate.max_fetch_depth 参数用于设置单向关联(一对一,多对一)的外连接抓取(outer join fetch)树的最大深度。其取值为 0 到 3 之间,建议取值为 1 或 2。 8. hibernate.default_batch_fetch_size ...

    hibernate源码下载

    文件名如`hibernate_fetch_5`、`hibernate_fetch_2`和`hibernate_fetch_4`暗示了对Hibernate数据获取策略的关注。在Hibernate中,Fetch策略包括EAGER(即时加载)和LAZY(延迟加载)。EAGER策略会立即加载关联的...

    Hibernate 参数配置详解

    例如,通过设置合适的 `hibernate.max_fetch_depth` 和 `hibernate.default_batch_fetch_size` 可以显著提升应用性能;而启用 `hibernate.generate_statistics` 则有助于我们更好地监控和分析应用性能瓶颈。此外,...

    hibernate aip hibernate aip

    8. **查询优化**:避免N+1查询问题,使用JOIN fetch提前加载关联数据,使用HQL或JPQL替代原生SQL以利用Hibernate的优化能力。 9. **错误处理和日志记录**:理解Hibernate常见的错误和异常,如 detached entity ...

    优化Hibernate性能的几点建议

    在使用Hibernate进行数据查询时,Fetch Size的设置对性能有着显著的影响。Fetch Size是指每次从数据库中取出的数据行数,默认情况下,Oracle数据库的JDBC驱动程序中的Fetch Size被设置为15。然而,将Fetch Size增加...

    Hibernate教程15_关联关系中的CRUD Cascade_Fetch

    在本教程中,我们将深入探讨Hibernate中的关联关系及其在CRUD操作中的应用,特别是关于Cascade和Fetch策略。Hibernate是Java领域广泛使用的对象关系映射(ORM)框架,它允许开发者用面向对象的方式来处理数据库交互...

    hibernate配置参数大全

    7. **`hibernate.max_fetch_depth`**:定义Hibernate执行外连接获取关联对象时的最大深度。 - 示例: ```properties hibernate.max_fetch_depth=3 ``` 8. **`hibernate.default_batch_fetch_size`**:定义默认...

    hibernate一对多项目

    若希望在获取父实体时同时加载子实体,可以设置`fetch = FetchType.EAGER`。 6. **缓存策略**: - Hibernate提供了一级缓存(Session级别)和二级缓存(SessionFactory级别)。合理设置缓存策略可以提高数据读取...

    Hibernate 参数设置一览表.doc

    6. **hibernate.max_fetch_depth**:它限制了外连接加载关联的深度,防止因过于深的关联导致大量数据加载。一般建议设置在0到3之间。 7. **hibernate.default_batch_fetch_size**:设置批量获取关联对象的数量,...

    Hibernate-基础联表模板

    综上所述,"Hibernate-基础联表模板"涵盖了Hibernate中关于联表查询的基础知识,包括各种查询方式、关联关系的定义、Fetch策略以及查询结果的处理等,是开发者进行数据库操作的有力助手。通过这个模板,开发者可以...

    HibernateDemo(hibernate基本用法演示)

    9. **延迟加载(Lazy Loading)**:通过 `@OneToMany(mappedBy = "..." fetch = FetchType.LAZY)` 可以实现懒加载,只有在真正需要时才会加载关联的对象,避免了数据冗余。 10. **事件监听**:可以注册事件监听器,...

    hibernate参数配置

    13. **hibernate.jdbc.fetch_size**: 设置JDBC抓取(fetch)大小,非零值,通过`Statement.setFetchSize()`控制。 14. **hibernate.jdbc.batch_size**: 用于启用JDBC2批量更新,建议值在5到30之间。 15. **...

    Hibernate3的配置参数汇总

    - `hibernate.max_fetch_depth`:控制外连接抓取的深度,默认值为0表示关闭。 - `hibernate.default_batch_fetch_size`:设置默认的批量抓取大小,提高查询性能。 - `hibernate.default_entity_mode`:定义...

    hibernate 配置属性参数详情(全)

    6. **hibernate.max_fetch_depth**:控制单向关联的外连接抓取深度,较高的值可能导致更多的数据库查询,建议值在0到3之间。 7. **hibernate.default_batch_fetch_size**:默认的批量抓取大小,可以提高性能,常见...

    hibernate配置文件hibernate.cfg.xml的详细解释

    - **Fetch Size**: `&lt;property name="jdbc.fetch_size"&gt;50&lt;/property&gt;` 控制Hibernate每次从数据库获取的数据量,较大的值可以减少查询次数,但会增加内存消耗。 - **Batch Size**: `...

    关于hibernate的批处理

    可以通过`@Fetch(FetchMode.JOIN)`或配置fetch profiles实现。 9. **ScrollableResult**: 使用 ScrollableResult 可以按需读取数据,而不是一次性加载所有结果,这对于大数据量查询非常有用,配合批处理可以有效...

Global site tag (gtag.js) - Google Analytics