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样式和批量大小也是需要慎重考虑的。

转载于:https://www.cnblogs.com/james1207/p/3275405.html

Hibernate 配置详解(5)相关推荐

  1. Hibernate配置详解

     一.简单介绍   Hibernate是一种对JDBC做了轻量级封装的对象---关系映射工具,所谓轻量级封装,是指Hibernate并没有完全封装JDBC,Java应用即可以通过Hibernate ...

  2. hibernate.hbm2ddl.auto配置详解

    hibernate.hbm2ddl.auto配置详解 http://www.cnblogs.com/feilong3540717/archive/2011/12/19/2293038.html hib ...

  3. 【Hibernate】hibernate主键生成策略与配置详解

    //####################################################### **Hibernate各种主键生成策略与配置详解** //############# ...

  4. (转)Hibernate的配置详解

    http://blog.csdn.net/yerenyuan_pku/article/details/65041077 在<Hibernate快速入门>一文中,我有讲到Hibernate的 ...

  5. struts2+hibernate+spring配置详解

    #struts2+hibernate+spring配置详解 struts2+hibernate+spring配置详解 哎 ,当初一个人做好难,现在终于弄好了,希望自学这个的能少走些弯路. 以下是自己配 ...

  6. SpringBoot的配置详解application

    SpringBoot的配置文件application有两种文件格式,两种配置的内容是一致的,只是格式不一致. 1.application.properties 2.application.yml或者a ...

  7. SpringBoot—整合log4j2入门和log4j2.xml配置详解

    关注微信公众号:CodingTechWork,一起学习进步. 引言   对于一个线上程序或者服务而言,重要的是要有日志输出,这样才能方便运维.而日志的输出需要有一定的规划,如日志命名.日志大小,日志分 ...

  8. ssh2的application.xml配置文件配置详解

    ssh2的application.xml配置文件配置详解 1.导入其他的配置文件.在ssh项目中可以导入其他的配置文件,导入的格式为: <import resource="classp ...

  9. SpringBoot整合Log4j2以及配置详解

    文章目录 标题SpringBoot整合Log4j2以及配置详解 1.加入依赖 2.在src.java.main.resources目录下创建log4j2.xml文件 log4j2.xml文件内容如下: ...

最新文章

  1. 【javaweb】Session原理以及浏览器禁止Cookie之后服务器如何获取Session
  2. node服务的监控预警系统架构
  3. 计算机职称考试软盘,2010年职称计算机考试:磁盘格式化
  4. Kendo Web UI Grid里时间格式转换
  5. 绘制几何图形——使用android.graphics类 onDraw
  6. 10-angular.identity
  7. java加法运算器界面_Java 接口实现计算器加减乘除(字符交互界面)
  8. 美国科技投资交易约4.1%来自中国 投资仍然很困难
  9. kafka为什么用java重写,kafka怎么发布订阅 怎么在java中实现
  10. NameValueCollection Dictionary区别
  11. Adams入门详解与实例(第2版)pdf电子书
  12. Python学习心得体会
  13. CO BW成本报表建立小结
  14. KF与无迹卡尔曼滤波详解
  15. python path包的使用详解
  16. 偏航角、俯仰角、横滚角的理解
  17. Apple 投诉网站
  18. 1418:猴子选大王
  19. google 访问统计
  20. Liblinear库编译

热门文章

  1. 平舌音 Z C S 的正确发音方式
  2. 如何开发 Servlet 程序
  3. c语言解析分隔符文本,c – 使用分隔符读取文件
  4. python selenium 点击开始按钮_使用Selenium和Python单击一个按钮
  5. 多元回归求解 机器学习_金融领域里的机器学习算法介绍:人工神经网络
  6. 嵩天python笔记_嵩天Python学习笔记-05
  7. java笔试题_Java面试才到笔试就没有然后了?快来签收,高频笔试57题及解答
  8. html ctf查找,Web CTF 解题思路总结—南京邮电大学攻防平台writeup
  9. html文档的基本类型,HTML(网页的文档类型介绍)
  10. microsoftexchange邮箱容量怎样看_企业邮箱申请注册的要求有哪些?_网站建设_创客网络...