hibernate抓取策略,单端代理的批量抓取
保持默认,同fetch="select",如:
<many-to-one name="dept" class="entity.Dept" fetch="select">
fetch="select",另外发送一条select语句加载当前对象的关联对象或集合
fetch为select或join不影响hql,它影响的是load,get方法
Emp emp = (Emp) session.get(Emp.class, new Short("7369"));
System.out.println(emp.getEname());
Dept dept = emp.getDept();
System.out.println("dept.name=" + dept.getDname());
(两条sql语句)
hibernate抓取策略,单端代理的批量抓取
设置fetch="join",如:
<many-to-one name="dept" class="entity.Dept" fetch="join">
fetch="join",hibernate会通过一个select语句连接(内联/外联)抓取其关联对象或集合
fetch="join",那么lazy失效
fetch="join",只影响get和load,对hql没有影响
Emp emp = (Emp) session.get(Emp.class, new Short("7369"));
System.out.println(emp.getEname());
Dept dept = emp.getDept();
System.out.println("dept.name=" + dept.getDname());
(一条sql语句)
<many-to-one>可能会出现N+1问题,
如:查询100个员工显示到列表中:
* 首先会发出查询员工的sql语句
* 然后会发出根据部门id查询部门的sql语句
这样就会导致N+1问题,也就是发出了N+1条语句,会严重影响性能
所以我们可以采用预先抓取的策略,如:
select s from Emp s join fetch s.dept
(这样子就是 2条sql语句)
hibernate抓取策略,集合代理的批量抓取
保持默认,同fetch="select",如:
<set name="emps" inverse="true" fetch="select">
fetch="select",另外发送一条select语句加载当前对象的关联对象或集合
Dept dept = (Dept) session.get(Dept.class, new Byte("20"));
System.out.println("dept.name=" + dept.getDname());
for (Iterator iter=dept.getEmps().iterator(); iter.hasNext();) {
Emp emp = (Emp)iter.next();
System.out.println(emp.getEname());
}
(根据deptno查询)
(两条sql语句)
hibernate抓取策略,集合代理的批量抓取
保持默认,同fetch="select",如:
<set name="emps" inverse="true" fetch="join">
fetch="select",另外发送一条select语句加载当前对象的关联对象或集合
Dept dept = (Dept) session.get(Dept.class, new Byte("20"));
System.out.println("dept.name=" + dept.getDname());
for (Iterator iter=dept.getEmps().iterator(); iter.hasNext();) {
Emp emp = (Emp)iter.next();
System.out.println(emp.getEname());
}
(一条sql语句)
hibernate抓取策略,集合代理的批量抓取
设置fetch="subselect",如:
<set name="emps" inverse="true" fetch="subselect">
fetch="subselect",另外发送一条select语句抓取在前面查询到的所有实体的关联集合
fetch="subselect",会影响hql查询
List deptList = session.createQuery("select d from Dept d where d.deptno in('10', '20', '30')").list();
for (Iterator iter1=deptList.iterator(); iter1.hasNext();) {
Dept de = (Dept)iter1.next();
System.out.println(de.getDname());
for (Iterator iter=de.getEmps().iterator(); iter.hasNext();) {
Emp emt = (Emp)iter.next();
System.out.println(emt.getEname());
}
}
(2条否则会是四条语句)
hibernate抓取策略,batch-size在<dept>的应用
batch-size属性,可以批量加载实体类,参见Classes.hbm.xml
<class name="entity.Dept" batch-size="10">
解决N+1问题
(查询每个员工所对应的部门的id在根据id查询部门会发出N条查询语句这样就可以解决此问题)
hibernate抓取策略,batch-size在集合上的应用
batch-size属性,可以批量加载实体类,参见Dept.hbm.xml
<set name="emps" inverse="true" batch-size="4">
List deptList = session.createQuery("select d from Dept d").list();
for (Iterator iter1=deptList.iterator(); iter1.hasNext();) {
Dept de = (Dept)iter1.next();
System.out.println(de.getDname());
for (Iterator iter=de.getEmps().iterator(); iter.hasNext();) {
Emp emt = (Emp)iter.next();
System.out.println(emt.getEname());
}
}
(2条否则会是五条语句)(查询是根据部门的id查询)
在hibernate中的配置
//批量更新
<property name="hibernate.jdbc.batch_size">30</property>
//批量抓取参数
<property name="hibernate.jdbc.fetch_size">50</property>