本文主要给大家展示“Fetch在Hibernate中有什么用”,简单易懂,条理清晰,希望能帮你解决疑惑。让边肖带领你学习《在冬眠中取东西有什么用》一文。
现在越来越发现掌握Hibernate Fetch并不容易。Spring实际上使用起来要简单得多,但是在使用Hibernate的时候确实需要积累一定的时间。对于一个项目团队来说,如果使用Hibernate***,会有一个对Hibernate很了解的人,否则遇到问题就会变成项目风险。
我想告诉你的是,掌握Hibernate Fetch可能比你想象的要困难得多。当你轻松告诉我Hibernate Fetch很简单的时候,你就该多反思一下自己了。(只有一个例外,你是牛。)
嗯,引言里废话太多了。其实今天我只想先说一下Hibernate Fetch的功能。
众所周知,在Hibernate中,引入懒惰的概念是为了性能。在这里,我们以父母和孩子为模型来说明。
publicclassparentimplesserializable {/* * identifier field */privateongid;/* * persistent field */privatesticlds;//skippalgetter/settermethod } publicclasschildimplesserializable {/* * identifier field */privateongid;/* * persistent field */private net . foxlog . model . parentparent;////skipalgetter/settermethod } }当我们查询Parent对象时,默认情况下只有Parent的内容不包含子对象的信息。如果在Parent.hbm.xml中设置了lazy='false ',将同时获取所有相关的子内容。
问题是,如果我既想要Hibernate的默认性能,又想要暂时的灵活性,该怎么办?这是Fetch的功能。我们可以将fetch和lazy='true '之间的关系与事务中的编程事务和声明性事务进行比较,这并不准确,但它可能意味着这一点。
总的价值,fetch,是给你一个机会在代码级别采取主动。
parentparent=(Parent)hibernate template . execute(new hibernate callback(){ publicatobjectdoinhibernate(session ession)throwsHibernateException,SQLException { Queryq=session . createquery(nb
sp; "from Parent as parent "+ " left outer join fetch parent.childs " + " where parent.id = :id" ); q.setParameter("id",new Long(15)); return (Parent)q.uniqueResult(); } }); Assert.assertTrue(parent.getChilds().size() > 0);
你可以在lazy="true"的情况下把Fetch去掉,就会报异常. 当然,如果lazy="false"就不需要fetch了有一个问题,使用Fetch会有重复记录的现象发生,我们可以理解为Fetch实际上不是为Parent服务的,而是为Child服务的.所以直接取Parent会有不匹配的问题.
参考一下下面的这篇文章 Hibernate集合初始化
update:以上有些结论错误,实际上在Hibernate3.2.1版本下测试,可以不出现重复记录,
public void testNPlusOne() throws Exception{ List list = (List)hibernateTemplate.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { Query q = session.createQuery( "select distinct p from net.foxlog.model.Parent p inner join fetch p.childs" ); return q.list(); } }); //((Parent)(list.get(0))).getChilds(); System.out.println("list size = " + list.size()); for(int i=0;i<list.size();i++){ Parent p = (Parent)list.get(i); System.out.println("===parent = " + p); System.out.println("===parent's child's length = " + p.getChilds().size()); } }
打印结果如下:
Hibernate: select distinct parent0_.id as id2_0_, childs1_.id as id0_1_, childs1_.parent_id as parent2_0_1_, childs1_.parent_id as parent2_0__, childs1_.id as id0__ from parent parent0_ inner join child childs1_ on parent0_.id=childs1_.parent_id list size = 3 ===parent = net.foxlog.model.Parent@1401d28[id=14] ===parent's child's length = 1 ===parent = net.foxlog.model.Parent@14e0e90[id=15] ===parent's child's length = 2 ===parent = net.foxlog.model.Parent@62610b[id=17] ===parent's child's length = 3
另外,如果用open session in view模式的话一般不用Fetch,但首先推荐Fetch,如果非用的话因为有N+1的现象,所以可以结合batch模式来改善下性能.
以上是“Hibernate里的Fetch有什么用”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/137016.html