Hibernate中的fetch

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>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值