hibernate抓取策略fetch具體解釋
1、hibernate抓取策略(單端代理的批量抓取fetch=select(默認)/join)
測試用例:
Student student = (Student)session.get(Student.class, 1);
System.out.println(student.getName());
System.out.println(student.getClasses().getName());session
1)保持默認,同fetch="select",如:
<many-to-one name="classes" column="classesid" fetch="select"/>性能
fetch="select",另外發送一條select語句抓取當前對象關聯實體或集合fetch
hibernate抓取策略fetch具體解釋
運行結果:2條語句spa
Hibernate: select student0_.id as id1_0_, student0_.name as name1_0_, student0_.class_id as class3_1_0_ from student_join student0_ where student0_.id=?
學生1
Hibernate: select classes0_.id as id0_0_, classes0_.name as name0_0_ from classes_join classes0_ where classes0_.id=?
高一(1)班
2)設置fetch="join",如:
<many-to-one name="classes" column="classesid" fetch="join"/>hibernate
fetch="join",hibernate會經過select語句使用外鏈接來載入其關聯實體或集合代理
hibernate抓取策略fetch具體解釋
此時lazy會失效xml
運行結果:一條join語句對象
Hibernate: select student0_.id as id1_1_, student0_.name as name1_1_, student0_.class_id as class3_1_1_, classes1_.id as id0_0_, classes1_.name as name0_0_ from student_join student0_ left outer join classes_join classes1_ on student0_.class_id=classes1_.id where student0_.id=?
學生1
高一(1)班
2、hibernate抓取策略(集合代理的批量抓取,fetch=select(默認)/join/subselect)blog
測試用例:get
Classes c = (Classes) session.load(Classes.class, new Integer(1));
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());
}
}
1)hibernate抓取策略fetch具體解釋
保持默認,同fetch="select",如:
<set name="students" inverse="true" fetch="select">
fetch="select",另外發送一條select語句抓取當前對象關聯實體或集合
測試結果:2條獨立的查詢語句
Hibernate: select classes0_.id as id0_0_, classes0_.name as name0_0_ from classes_join classes0_ where classes0_.id=?
Class.name=高一(1)班
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=?
9
student.name=學生7
student.name=學生3
student.name=學生1
student.name=學生8
student.name=學生2
student.name=學生4
student.name=學生5
student.name=學生9
student.name=學生6
(2)設置fetch="join",如:
<set name="students" inverse="true" fetch="join">
fetch="join",hibernate會經過select語句使用外鏈接來載入其關聯實體或集合
此時lazy會失效
測試結果:1條獨立的join查詢語句
Hibernate: select classes0_.id as id0_1_, classes0_.name as name0_1_, students1_.class_id as class3_3_, students1_.id as id3_, students1_.id as id1_0_, students1_.name as name1_0_, students1_.class_id as class3_1_0_ from classes_join classes0_ left outer join student_join students1_ on classes0_.id=students1_.class_id where classes0_.id=?
Class.name=高一(1)班
9
student.name=學生6
student.name=學生4
student.name=學生9
student.name=學生7
student.name=學生2
student.name=學生3
student.name=學生8
student.name=學生1
student.name=學生5
(3)設置fetch="subselect",如:用在查詢語句中
<set name="students" inverse="true" fetch="subselect">
fetch="subselect",另外發送一條select語句抓取在前面查詢到的所有實體對象的關聯集合
測試用例:
List classList = session.createQuery("from Classes where id in (1,2,3)").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());
}
}
}
當不設fetch="subselect" ,即:<set name="students" inverse="true">,結果例如如下:
運行了3條查詢語句
Hibernate: select classes0_.id as id0_, classes0_.name as name0_ from classes_join classes0_ where classes0_.id in (1 , 2 , 3)
Class.name=高一(1)班
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=?
9
student.name=學生8
student.name=學生5
student.name=學生3
student.name=學生9
student.name=學生7
student.name=學生1
student.name=學生4
student.name=學生6
student.name=學生2
Class.name=高一(2)班
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=?
4
student.name=學生3
student.name=學生4
student.name=學生1
student.name=學生2
Class.name=高一(3)班
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=?
0
當不設fetch="subselect" ,即:<set name="students" inverse="true" fetch="subselect">,結果例如如下:
運行了1條查詢語句(嵌套子查詢)
Hibernate: select classes0_.id as id0_, classes0_.name as name0_ from classes_join classes0_ where classes0_.id in (1 , 2 , 3)
Class.name=高一(1)班
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 (select classes0_.id from classes_join classes0_ where classes0_.id in (1 , 2 , 3))
------------------------------------------------------
總結:
hibernate抓取策略(單端代理的批量抓取) 保持默認,同fetch="select",如: fetch="select",另外發送一條select語句抓取當前對象關聯實體或集合
2.hibernate抓取策略(單端代理的批量抓取) 設置fetch="join",如: fetch="join",hibernate會經過select語句使用外鏈接來載入其關聯實體或集合 此時lazy會失效
3.hibernate抓取策略(集合代理的批量抓取) 保持默認,同fetch="select",如: fetch="select",另外發送一條select語句抓取當前對象關聯實體或集合
4.hibernate抓取策略(集合代理的批量抓取) 設置fetch="join",如: fetch="join",hibernate會經過select語句使用外鏈接來載入其關聯實體或集合 此時lazy會失效 5.hibernate抓取策略(集合代理的批量抓取) 設置fetch="subselect",如: fetch="subselect",另外發送一條select語句抓取在前面查詢到的所有實體對象的關聯集合
6.hibernate抓取策略,,batch-szie在<class>上的應用 batch-size屬性,可以批量載入實體類,參見:Classes.hbm.xml 當查classes對象時發出9條hql語句配置事後batch-size=3後會之發9/3=3條hql語句,提升性能
7.hibernate抓取策略,batch-szie在集合上的應用
當查students對象時發出10條hql語句配置事後batch-size=5後會之發10/5=2條hql語句,提升性能
總體上分析:默認是fetch="select" 當配置fetch="join"時直接查詢包括的對象或者集合lazy失效。 |