Hibernate 配置详解(5)
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)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑系统怎样改字体(电脑系统怎么改字体)
- 下一篇: java数组复制的方式和效率比较