One one = (One)session.get(One.class,new Integer(1)); Iterator iterone = one.getTwos().iterator(); while(iterone.hasNext()){ Two two = (Two) iterone.next(); Iterator itertwo = two.getThrees().iterator(); while(itertwo.hasNext()){ Three three = (Three) itertwo.next(); three.getFours().size(); } }
q样我在Session关闭后返回的One里是从One到Four的信息都有的?BR>然而这样做所D的结果是生成大量的SQL查询Q这是一个典型的n+1 Selects问题。如果系l结构层ơ多Q符合条件的记录多,那么HibernateZ生成的SQL查询是难以接受的?BR>对于q个例子生成的SQL是这L Hibernate: select one0_.c_one_id as c1_0_, one0_.c_one_text as c2_3_0_ from One one0_ where one0_.c_one_id=? Hibernate: select twos0_.c_one_id as c2_1_, twos0_.c_two_id as c1_1_, twos0_.c_two_id as c1_0_, twos0_.c_one_id as c2_2_0_, twos0_.c_two_text as c3_2_0_ from Two twos0_ where twos0_.c_one_id=? Hibernate: select threes0_.c_two_id as c2_1_, threes0_.c_three_id as c1_1_, threes0_.c_three_id as c1_0_, threes0_.c_two_id as c2_1_0_, threes0_.c_three_text as c3_1_0_ from Three threes0_ where threes0_.c_two_id=? Hibernate: select fours0_.c_three_id as c2_1_, fours0_.c_four_id as c1_1_, fours0_.c_four_id as c1_0_, fours0_.c_three_id as c2_0_0_, fours0_.c_four_text as c3_0_0_ from Four fours0_ where fours0_.c_three_id=? Hibernate: select fours0_.c_three_id as c2_1_, fours0_.c_four_id as c1_1_, fours0_.c_four_id as c1_0_, fours0_.c_three_id as c2_0_0_, fours0_.c_four_text as c3_0_0_ from Four fours0_ where fours0_.c_three_id=? Hibernate: select threes0_.c_two_id as c2_1_, threes0_.c_three_id as c1_1_, threes0_.c_three_id as c1_0_, threes0_.c_two_id as c2_1_0_, threes0_.c_three_text as c3_1_0_ from Three threes0_ where threes0_.c_two_id=? Hibernate: select fours0_.c_three_id as c2_1_, fours0_.c_four_id as c1_1_, fours0_.c_four_id as c1_0_, fours0_.c_three_id as c2_0_0_, fours0_.c_four_text as c3_0_0_ from Four fours0_ where fours0_.c_three_id=? Hibernate: select fours0_.c_three_id as c2_1_, fours0_.c_four_id as c1_1_, fours0_.c_four_id as c1_0_, fours0_.c_three_id as c2_0_0_, fours0_.c_four_text as c3_0_0_ from Four fours0_ where fours0_.c_three_id=? 对于q样的问题,在没有Hibernate以前我们一般都用jdbc来做Q那L话我们其实用一个进?ơjoin的sql语句可以实玎ͼ但是q样解决也有问题Q就是返回的ResultSet中的数据非常多,而且杂ؕQ其实是从one到fourq排列的。对于这Ll果集我们要把它手动影射曑֯象结构也是一个很复杂的操作?BR>q好Hibernate3可以为我们做q些事情(我再一ơ被Hibernate的强大所震撼)?BR>上面的实现可以用Criteria来实玎ͼ
q里的重Ҏq句话criteria.setFetchMode("twos",FetchMode.JOIN).setFetchMode("twos.threes",FetchMode.JOIN).setFetchMode("twos.threes.fours",FetchMode.JOIN).uniqueResult(); 在用Criteria之前先设|FetchModeQ应为Criteria是动态生成sql语句的,所以生成的sql是一层层Join下去的?BR>setFetchModeQStringQModeQ第一个参数是association pathQ用"."来表C\径。这一点具体的例子很少Q文也没有写清楚。我也是试了很久才试出来的?BR>p个例子来所把因为取道第四层Q所以要q行三次setFetchMode W一ơ的路径是twosQ一位one中有two的Set。这个具体要更具hbm.xml的配|来定?BR>W二个\径就是twos.threes W三个就是twos.threes.fours 一ơ类推,一层层增加的?BR>q样做法最l生成的SQL是这LQ?BR>Hibernate: select this_.c_one_id as c1_3_, this_.c_one_text as c2_3_3_, twos2_.c_one_id as c2_5_, twos2_.c_two_id as c1_5_, twos2_.c_two_id as c1_0_, twos2_.c_one_id as c2_2_0_, twos2_.c_two_text as c3_2_0_, threes3_.c_two_id as c2_6_, threes3_.c_three_id as c1_6_, threes3_.c_three_id as c1_1_, threes3_.c_two_id as c2_1_1_, threes3_.c_three_text as c3_1_1_, fours4_.c_three_id as c2_7_, fours4_.c_four_id as c1_7_, fours4_.c_four_id as c1_2_, fours4_.c_three_id as c2_0_2_, fours4_.c_four_text as c3_0_2_ from One this_ left outer join Two twos2_ on this_.c_one_id=twos2_.c_one_id left outer join Three threes3_ on twos2_.c_two_id=threes3_.c_two_id left outer join Four fours4_ on threes3_.c_three_id=fours4_.c_three_id where this_.c_one_id=? 虽然很长但是只有一条SQL语句。性能要好很多。Hibernate的强大之处是它会把返回的ResultSet自动影射C的对象模型里面去。这׃ؓ我们省了很多事?BR> 看来Hibernate真是一个耐hd的Framework啊?BR> 源码Q没什么东ѝ?BR>http://www.aygfsteel.com/Files/mstar/HiberFetch2.rar
如果你把HQL写成q个样子Q?BR>update Contact as c set c.relationShip.relationId =1 ...... 反而会出错Q也是_你就按照native SQLdp了?BR>q有Q如果能使用q样的功?BR>hibernate.query.factory_class = org.hibernate.hql.classic.ClassicQueryTranslatorFactory q个Hibernate配置属性要不去掉,要不换成org.hibernate.hql.ast.ASTQueryTranslatorFactory 上面那个是支持Hibernate2的?BR>但是有一点要注意Q如果你用update语句来做的话Q可能生缓存同步问题,而且两种Ҏ最后Hibernate执行的语句差不多Q对于第一U方法Hibernate也是q成一条update语句Q当然因为我是根据主键来update的,如果扚w处理的话q是用Update HQL快?BR>
]]>Could not initialize proxy - the owning Session was closedhttp://www.aygfsteel.com/mstar/archive/2005/09/05/12125.html黑灵黑灵Mon, 05 Sep 2005 15:57:00 GMThttp://www.aygfsteel.com/mstar/archive/2005/09/05/12125.htmlhttp://www.aygfsteel.com/mstar/comments/12125.htmlhttp://www.aygfsteel.com/mstar/archive/2005/09/05/12125.html#Feedback1http://www.aygfsteel.com/mstar/comments/commentRss/12125.htmlhttp://www.aygfsteel.com/mstar/services/trackbacks/12125.htmlHibernatecȝinitialize()静态方法用于在Session范围内显式初始化代理cd例,isInitialized()Ҏ用于判断代理cd例是否已l被初始化。例如: