测试方法
public void testLazy(){
QX qx=(QX)get(QX.class,1);
System.out.println(qx.getQxname());
try {
Thread.sleep(3000);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Iterator it= qx.getJds().iterator();
while(it.hasNext()){
System.out.print(((JD)it.next()).getJdname());
}
QX(区县)和JD(街道)是一对多关系,这个里面读取QX的名称,过3秒钟后,去读该区县里面JD的名称。
hbm关于set的代码是
在cfg中,设定输出SQL语句
=======================================================================================
1、不设定lazy和fetch的时候
控制台输出为
Hibernate: select qx0_.qxid as qxid1_0_, qx0_.qx as qx1_0_ from TBL_QX qx0_ where qx0_.qxid=?
海淀
Hibernate: select jds0_.qxid as qxid1_, jds0_.jdid as jdid1_, jds0_.jdid as jdid2_0_, jds0_.jd as jd2_0_, jds0_.qxid as qxid2_0_ from TBL_JD jds0_ where jds0_.qxid=?
公主坟动物园五四大道中关村
说明是多次查询,类中的代码延迟加载。
2、设定lazy=“true”的时候
Hibernate: select qx0_.qxid as qxid1_0_, qx0_.qx as qx1_0_ from TBL_QX qx0_ where qx0_.qxid=?
海淀
Hibernate: select jds0_.qxid as qxid1_, jds0_.jdid as jdid1_, jds0_.jdid as jdid2_0_, jds0_.jd as jd2_0_, jds0_.qxid as qxid2_0_ from TBL_JD jds0_ where jds0_.qxid=?
公主坟动物园五四大道中关村
说明有lazy起到延迟加载的目的,即是当需要查询所包含内容的时候,才会去查询。
同时也说明,默认lazy是true的。
3、设定lazy=“false”的时候
Hibernate: select qx0_.qxid as qxid1_0_, qx0_.qx as qx1_0_ from TBL_QX qx0_ where qx0_.qxid=?
Hibernate: select jds0_.qxid as qxid1_, jds0_.jdid as jdid1_, jds0_.jdid as jdid2_0_, jds0_.jd as jd2_0_, jds0_.qxid as qxid2_0_ from TBL_JD jds0_ where jds0_.qxid=?
海淀
五四大道公主坟动物园中关村
说明当lazy为false,一次查询所有结果。
4、设定lazy=“true”,fetch=“join”的时候
Hibernate: select qx0_.qxid as qxid1_1_, qx0_.qx as qx1_1_, jds1_.qxid as qxid3_, jds1_.jdid as jdid3_, jds1_.jdid as jdid2_0_, jds1_.jd as jd2_0_, jds1_.qxid as qxid2_0_ from TBL_QX qx0_ left outer join TBL_JD jds1_ on qx0_.qxid=jds1_.qxid where qx0_.qxid=?
海淀
五四大道公主坟动物园中关村
即时lazy为true,一个一次查询所有结果,没有延时,说明fetch权限大于lazy。
查询是用一个select语句,用join拼接结果。
5、设定lazy=“true” fetch=“select”的时候
Hibernate: select qx0_.qxid as qxid1_0_, qx0_.qx as qx1_0_ from TBL_QX qx0_ where qx0_.qxid=?
海淀
Hibernate: select jds0_.qxid as qxid1_, jds0_.jdid as jdid1_, jds0_.jdid as jdid2_0_, jds0_.jd as jd2_0_, jds0_.qxid as qxid2_0_ from TBL_JD jds0_ where jds0_.qxid=?
公主坟动物园五四大道中关村
延时加载,分两条select查询。
6、设定lazy=“false” fetch=“select”的时候
Hibernate: select qx0_.qxid as qxid1_0_, qx0_.qx as qx1_0_ from TBL_QX qx0_ where qx0_.qxid=?
Hibernate: select jds0_.qxid as qxid1_, jds0_.jdid as jdid1_, jds0_.jdid as jdid2_0_, jds0_.jd as jd2_0_, jds0_.qxid as qxid2_0_ from TBL_JD jds0_ where jds0_.qxid=?
海淀
五四大道公主坟动物园中关村
一次查询,但是是用两条select语句
==================================================================================
最后说明:
结论1: HQL代码 > fetch(配置) > lazy (配置)
结论2: 默认 lazy="true"
结论3: fetch 和 lazy 主要是用来级联查询的,
fetch参数指定了关联对象抓取的方式是select查询还是join查询,select方式时先查询返回要查询的主体对象(列表),再根据关联外键id,每一个对象发一个select查询,获取关联的对象,形成n+1次查 询; 而join方式,主体对象和关联对象用一句外键关联的sql同时查询出来,不会形成多次查询,也不会延迟加载。
如果你的关联对象是延迟加载的,它当然不会去查询关联对象。 另外,在hql查询中配置文件中设置的join方式是不起作用的(而在所有其他查询方式如get、criteria或再关联获取等等都是有效的),会使用select方式,除非你在hql中指定join fetch某个关联对象。fetch策略用于定义 get/load一个对象时,如何获取非lazy的对象/集合。 这些参数在Query中无效。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/22259926/viewspace-665110/ ,如需转载,请注明出处,否则将追究法律责任。