9) hibernate.batch_fetch_style:

该配置是hibernate4.2.0新添加的,使用这个设置可以配置hibernate在做batch-fetch的时候,生成SQL的策略。该配置项的可选值为org.hibernate.loader.BatchFetchStyle这个枚举类型中的可选值。所以,目前有三个选项:LEGACY,PADDED和DYNAMIC。下面分别介绍:

1,LEGACY:该批量抓取样式从一个预定义的数组中获取指定的匹配的个数来包装in后面的问号的个数,这个预定义的数组由org.hibernate.internal.util.collections.ArrayHelper#getBatchSizes 方法得到的。LEGACY也是该配置项的默认值。举一个简单的例子,假如向数据表中插入39条数据:

@Before
public void save() {
for (int i = 0; i < 39; i++) {
Department d = new Department();
d.setName("d" + i);
Employee e=new Employee();
e.setName("e"+i);
e.setDept(d);
Session session = HibernateUtil.getInstance().getSession();
session.beginTransaction();
session.save(d);
session.save(e);
session.getTransaction().commit();
session.close();
}
}

如果要批量获取,batch-fetch大小设置为14:

@Test
public void testBatchFetch() {
Session session = HibernateUtil.getInstance().getSession();
List emps = session.createQuery("FROM Employee").list();
for (Employee emp : emps) {
System.out.printf("employee:%s belong %s department \r\n",
emp.getId(), emp.getDept().getName());
}
session.close();
}

得到所有的Employee,并遍历访问Employee对应的Department,批量大小设置为14:

<class name="Department" batch-size="14">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<set name="emps">
<key column="DEPT_ID"/>
<one-to-many class="Employee"/>
</set>
</class>

在hibernate.properties文件中配置:

hibernate.batch_fetch_style LEGACY

运行测试,输出内容(简化之后):

Hibernate: select employee0_.id as id1_1_, employee0_.name as name2_1_, employee0_.DEPT_ID as DEPT3_1_ from Employee employee0_

Hibernate: select department0_.id as id1_0_0_, department0_.name as name2_0_0_ from Department department0_ where department0_.id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

employee:1 到 employee:14

Hibernate: select department0_.id as id1_0_0_, department0_.name as name2_0_0_ from Department department0_ where department0_.id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

employee:15 到 employee:28

Hibernate: select department0_.id as id1_0_0_, department0_.name as name2_0_0_ from Department department0_ where department0_.id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

employee:28 到 employee:38

Hibernate: select department0_.id as id1_0_0_, department0_.name as name2_0_0_ from Department department0_ where department0_.id=?

employee:39

可以很清楚的看出,在连续使用14批量拿了两次数据之后,并没有直接把最后一个批量的数据(11个)一次性的拿出来,而是分别使用了10+1的方式分了两次拿到数据。原理分析如下:

首先根据设置的batch-size=14,把14作为最大的batch数传给org.hibernate.internal.util.collections.ArrayHelper#getBatchSizes方法,得到一个预处理的数组为:[14,10,9,8,7,6,5,4,3,2,1],换句话说,能够放到IN后面的批量的数字只能是这个数组中的某一个值,所以,第一次取,39>14,取最大批量14,第二次取,25>14,取最大批量14,第三次取11<14,所以只能取第二大的11>10,取10批量,最后一次取,取1个。这种策略就很清晰了。

2,PADDED:该方式和LEGACY一样,从一个预定义的数组中获取指定的匹配的个数来包装in后面的问号的个数,这个预定义的数组由org.hibernate.internal.util.collections.ArrayHelper#getBatchSizes 方法得到的。和LEGACY不同的是,当余下的数量不够的时候,该方式总会选择一个大于当前匹配批量的数量。相同的示例,我们修改批量样式为:

hibernate.batch_fetch_style PADDED

运行测试,控制台输出(简化之后):

Hibernate: select employee0_.id as id1_1_, employee0_.name as name2_1_, employee0_.DEPT_ID as DEPT3_1_ from Employee employee0_

Hibernate: select department0_.id as id1_0_0_, department0_.name as name2_0_0_ from Department department0_ where department0_.id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

employee:1 到employee:14

Hibernate: select department0_.id as id1_0_0_, department0_.name as name2_0_0_ from Department department0_ where department0_.id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

employee:15 到employee:28

Hibernate: select department0_.id as id1_0_0_, department0_.name as name2_0_0_ from Department department0_ where department0_.id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)

employee:29 到employee:39

可以清楚的看出PADDED和LEGACY的区别,PADDED只使用了3次批量就取出了所有的数据,取值流程为:

首先根据设置的batch-size=14,把14作为最大的batch数传给org.hibernate.internal.util.collections.ArrayHelper#getBatchSizes方法,得到一个预处理的数组为:[14,10,9,8,7,6,5,4,3,2,1],换句话说,能够放到IN后面的批量的数字只能是这个数组中的某一个值,所以,第一次取,39>14,取最大批量14,第二次取,25>14,取最大批量14,第三次取11<14,但是,PADDED会选择比10大1的数量,即选中14,然后用14把剩下的11个对象一次性的取出来了。

3,DYNAMIC:有多少数量,就直接使用一个批次全部拿出来,但是,还是不能超过设置的batch-size。所以,很好理解,如果使用DYNAMIC,也会使用14+14+14的方式分3次批量的把数据查询出来。

最后,可能有同学觉得使用PADDED+更大的batch-size就行了,其实也不是这样,因为毕竟是批量的去获取关联的数据,如果关联的数据过大,特别是批量的获取集合数据,得到的结果集越大,性能也会慢下来,所以,根据具体的应用需求合理的设置批量SQL样式和批量大小也是需要慎重考虑的。

Hibernate 配置详解(5)的更多相关文章

  1. Hibernate 配置详解(9)

    hibernate.cache.use_structured_entries Hibernate文档上介绍,该属性是用于把对象以一种更易读的方式放到二级缓存中,这样,在对二级缓存进行监控的时候就更容易 ...

  2. Hibernate 配置详解(2)

    6) hibernate.session_factory_name: 配置一个JNDI名称,通过Configuration对象创建的SessionFactory会绑定到JNDI下该名称中.一般名字格式 ...

  3. Hibernate 配置详解(8)

    hibernate.generate_statistics 这个配置大家应该都很熟悉,用于开启Hibernate统计信息,便于对Hibernate相关性能调试提供数据依据.在开发过程当中,可以把这个选 ...

  4. Hibernate 配置详解(12) 补充

    hibernate.hbm2ddl.import_files_sql_extractor 这个配置项用于补充这篇文章: http://blog.csdn.net/stefwu/article/deta ...

  5. Hibernate 配置详解(12) 其实我也不想用这么土的名字

    hibernate.hbm2ddl.import_files 这个配置用于在hibernate根据映射文件执行DDL之前,如果我们自己设置了要事先运行的SQL文件,hibernate就会先执行这些SQ ...

  6. Hibernate 配置详解(7)

    hibernate.order_updates: Hibernate文档中提到,该配置用于在刷新一级缓存,提交UPDATE的时候,按照每类对象的主键顺序排序后再提交,可以在高并发情况下减少事务死锁的可 ...

  7. Hibernate 配置详解(11)

    hibernate.session_factory_name_is_jndi 配置hibernate.cfg.xml中SessionFactory的name属性是否作为JNDI名称绑定.默认是true ...

  8. hibernate二级缓存ehcache hibernate配置详解

    <!-----------------hibernate二级缓存ehcache------------------------->hibernate配置 <prop key=&quo ...

  9. Hibernate配置详解

    <!--标准的XML文件的起始行,version='1.0'表明XML的版本,encoding='gb2312'表明XML文件的编码方式--> <?xml version='1.0' ...

随机推荐

  1. 使用php glob函数查找文件,遍历文件目录(转)

    函数说明:array glob ( string $pattern [, int $flags ] )功能:寻找与模式匹配的文件路径,返回包含匹配文件(目录)的数组(注:被检查的文件必须是服务器系统的 ...

  2. SSD -----TLC MLC SLC

    SLC缓存什么鬼?TLC评测造假要持续多久 2016.5.5来源:中关村在线 TLC的廉价真的将SSD引入了全面普及的高速公路上,谈到TLC我们更多的理解是TLC的P/E(Program/Erase ...

  3. Java语言基础(五)

    Java语言基础(五) 一.浮点数 浮点数就是小数,其标准是IEEE 754,用指数和尾数表示 例如30000=3*10000=3*10^4  其中4是指数,3是尾数 Java中,浮点数有float ...

  4. php 总结

    1.安装完apache之后 2.有一个目录 htdocs 下面就是根目录了 3.测试一下,新建一个index.html 写入 it works  .输入localhost 看是否显示 it works ...

  5. 四种数据持久化方式(下) :SQLite3 和 Core Data

    在上文,我们介绍了iOS开发中的其中2种数据持久化方式:属性列表.归档解档. 本节将继续介绍另外2种iOS持久化数据的方法:数据库 SQLite3.Core Data 的运用: 在本节,将通过对4个文 ...

  6. Java基础知识强化之集合框架笔记47:Set集合之TreeSet保证元素唯一性和比较器排序的原理及代码实现(比较器排序:Comparator)

    1. 比较器排序(定制排序) 前面我们说到的TreeSet的自然排序是根据集合元素的大小,TreeSet将它们以升序排列. 但是如果需要实现定制排序,比如实现降序排序,则要通过比较器排序(定制排序)实 ...

  7. jQuery 获取文件后缀的方法

    var location=$("input[name='file']").val(); var point = location.lastIndexOf("." ...

  8. Axiom3D学习日记 4.地形,天空,雾

    首先需要引用Axiom.SceneManagers.Octree.dll. 地形: 载入地形配置,从一个文件中. scene.LoadWorldGeometry( "Terrain.xml& ...

  9. HTML5+移动APP(2)

    原理: html 页面负责内容: ui 负责页面样式: js 负责调用原生app方法. html5: html5这部分负责页面,也就是app中你看到的东西,大概的架构和内容 ui: mui 介绍:和H ...

  10. 共享受限资源,Brian的同步规则

    说明:如果一个变量是boolean,则此变量是原子性的,即赋值和返回值简单的操作在发生时没有中断的可能. 递增不是原子性炒作. 解决共享资源竞争: 1. 通过加锁,锁语句会产生相互排斥的效果,此种机制 ...