batch_size 和 fetch_size作用
hibernate抓取策略,,batch-szie在<class>上的應用
batch-size屬性,可以批量加載實體類,
hbm.xml
classes.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.model">
????<class name="Classes" table="classes_join"?batch-size="3">
????????<id name="id" column="id" type="java.lang.Integer">
????????????<generator class="native" />
????????</id>
????????<property name="name" column="name" type="java.lang.String" />
????????<set name="students" >
????????????<key column="class_id" />
????????????<one-to-many class="com.model.Student" />
????????</set>
????</class>
</hibernate-mapping>
Student.hbm.xml
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping?package="com.model">
????<class name="Student" table="student_join" >
????????<id name="id" column="id" type="java.lang.Integer">
????????????<generator class="native" />?????????
????????</id>
????????<property name="name" column="name" length="50" type="java.lang.String" />
????????<many-to-one name="classes" column="class_id" ></many-to-one>
????</class>
</hibernate-mapping>
?
測試用例:
????List stuList = session.createQuery("from Student s where s.id in (:ids)")
?????????????????????????.setParameterList("ids", new Object[]{1,10})
?????????????????????????.list();
????for(Iterator it = stuList.iterator(); it.hasNext();){
?????Student stu =?(Student)it.next();
?????System.out.println(stu.getName());
?????System.out.println(stu.getClasses().getName());
????}
1)若沒配batch-size,即<class name="Classes" table="classes_join">
執行結果:執行2條班級查詢語句
Hibernate: select student0_.id as id1_, student0_.name as name1_, student0_.class_id as class3_1_ from student_join student0_ where student0_.id in (? , ?)
學生1
Hibernate:?select classes0_.id as id0_0_, classes0_.name as name0_0_ from classes_join classes0_ where classes0_.id=?
高一(1)班
學生1
Hibernate:?select classes0_.id as id0_0_, classes0_.name as name0_0_ from classes_join classes0_ where classes0_.id=?
高一(2)班
2)若配batch-size,即<class name="Classes" table="classes_join"?batch-size="5">
執行結果:執行1條班級查詢語句(每5個班級,發一條sql語句)
Hibernate: select student0_.id as id1_, student0_.name as name1_, student0_.class_id as class3_1_ from student_join student0_ where student0_.id in (? , ?)
學生1
Hibernate:?select classes0_.id as id0_0_, classes0_.name as name0_0_ from classes_join classes0_ where classes0_.id?in (?, ?)
高一(1)班
學生1
高一(2)班
?
===================================
hibernate抓取策略,batch-szie在集合上的應用
batch-size屬性,可以批量加載實體類,
<set name="students" batch-size="5">??
hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.model">
????<class name="Classes" table="classes_join" >
????????<id name="id" column="id" type="java.lang.Integer">
????????????<generator class="native" />
????????</id>
????????<property name="name" column="name" type="java.lang.String" />
????????<set name="students"?batch-size="5"?>
????????????<key column="class_id" />
????????????<one-to-many class="com.model.Student" />
????????</set>
????</class>
</hibernate-mapping>
測試用例:
List classList = session.createQuery("from Classes").list();
????for(Iterator iter = classList.iterator(); iter.hasNext();){
?????Classes c = (Classes)iter.next();
?????System.out.println("Class.name=" + c.getName());
?????Set stuSet = c.getStudents();
?????System.out.println(stuSet.size());
?????if(stuSet != null && !stuSet.isEmpty()){
??????for(Iterator it = stuSet.iterator(); it.hasNext();){
???????Student s = (Student) it.next();
???????System.out.println("student.name=" + s.getName());
??????}
?????}
????}
加了?<set name="students"?batch-size="5"?> //每5條,做一次查詢
如下:
Hibernate: select students0_.class_id as class3_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.class_id as class3_1_0_ from student_join students0_ where?students0_.class_id in (?, ?, ?, ?, ?)
Hibernate: select students0_.class_id as class3_1_, students0_.id as id1_, students0_.id as id1_0_, students0_.name as name1_0_, students0_.class_id as class3_1_0_ from student_join students0_ where?students0_.class_id in (?, ?, ?, ?)
?
=================================
hibernate.jdbc.fetch_size 和 hibernate.jdbc.batch_size
hibernate.jdbc.fetch_size 50 //讀
hibernate.jdbc.batch_size 30 //寫
?
hiberante.cfg.xml(Oracle ,sql server 支持,mysql不支持)
???<property name="hibernate.jdbc.fetch_size">50</property>
<property name="hibernate.jdbc.batch_size">30</property>
這兩個選項非常非常非常重要!!!將嚴重影響Hibernate的CRUD性能!
?
C = create, R = read, U = update, D = delete
?
Fetch Size 是設定JDBC的Statement讀取數據的時候每次從數據庫中取出的記錄條數。
?
例如一次查詢1萬條記錄,對于Oracle的JDBC驅動來說,是不會1次性把1萬條取出來的,而只會取出Fetch Size條數,當紀錄集遍歷完了這些記錄以后,再去數據庫取Fetch Size條數據。
?
因此大大節省了無謂的內存消耗。當然Fetch Size設的越大,讀數據庫的次數越少,速度越快;Fetch Size越小,讀數據庫的次數越多,速度越慢。
?
這有點像平時我們寫程序寫硬盤文件一樣,設立一個Buffer,每次寫入Buffer,等Buffer滿了以后,一次寫入硬盤,道理相同。
?
Oracle數據庫的JDBC驅動默認的Fetch Size=10,是一個非常保守的設定,根據我的測試,當Fetch Size=50的時候,性能會提升1倍之多,當Fetch Size=100,性能還能繼續提升20%,Fetch Size繼續增大,性能提升的就不顯著了。
?
因此我建議使用Oracle的一定要將Fetch Size設到50。
?
不過并不是所有的數據庫都支持Fetch Size特性,例如MySQL就不支持。
?
MySQL就像我上面說的那種最壞的情況,他總是一下就把1萬條記錄完全取出來,內存消耗會非常非常驚人!這個情況就沒有什么好辦法了 :(
?
Batch Size是設定對數據庫進行批量刪除,批量更新和批量插入的時候的批次大小,有點相當于設置Buffer緩沖區大小的意思。
?
Batch Size越大,批量操作的向數據庫發送sql的次數越少,速度就越快。我做的一個測試結果是當Batch Size=0的時候,使用Hibernate對Oracle數據庫刪除1萬條記錄需要25秒,Batch Size = 50的時候,刪除僅僅需要5秒!!!
//
我們通常不會直接操作一個對象的標識符(identifier), 因此標識符的setter方法應該被聲明為私有的(private)。這樣當一個對象被保存的時候,只有Hibernate可以為它分配標識符。 你會發現Hibernate可以直接訪問被聲明為public,private和protected等不同級別訪問控制的方法(accessor method)和字段(field)。 所以選擇哪種方式來訪問屬性是完全取決于你,你可以使你的選擇與你的程序設計相吻合。
所有的持久類(persistent classes)都要求有無參的構造器(no-argument constructor); 因為Hibernate必須要使用Java反射機制(Reflection)來實例化對象。構造器(constructor)的訪問控制可以是私有的(private), 然而當生成運行時代理(runtime proxy)的時候將要求使用至少是package級別的訪問控制,這樣在沒有字節碼編入 (bytecode instrumentation)的情況下,從持久化類里獲取數據會更有效率一些。
?
?
而
?
| hibernate.max_fetch_depth | 設置外連接抓取樹的最大深度 取值.?建議設置為0到3之間 |
就是每次你在查詢時,會級聯查詢的深度,譬如你對關聯vo設置了eager的話,如果fetch_depth值太小的話,會發多很多條sql
?
轉載于:https://www.cnblogs.com/servlet/p/4863770.html
總結
以上是生活随笔為你收集整理的batch_size 和 fetch_size作用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java-protected的使用范围
- 下一篇: CLLocationManager 位置