您好,登录后才能下订单哦!
这篇文章主要为大家展示了“Hibernate里的Fetch有什么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Hibernate里的Fetch有什么用”这篇文章吧。
现在越来越发现其实掌握Hibernate Fetch 并不容易,Spring用起来其实简单多了,但是在用Hibernate的时候真的是需要一定的时间积累,对一个项目组来说如果采用Hibernate***有一个对Hibernate比较清楚的人否则碰到问题就会成为项目的风险。
我想告诉各位的是,掌握Hibernate Fetch可能比你预期的难多了,当你轻松的告诉我,Hibernate Fetch很简单的时候该是你自己多反省了. (只有一种情况例外,你是一个牛人)
好了,一个引子废话那么多,其实今天只是想先说一说Hibernate Fetch的作用.
大家都知道,在Hibernate里为了性能考虑,引进了lazy的概念,这里我们以Parent和Child为模型来说明
public class Parent implements Serializable { /** identifier field */ private Long id; /** persistent field */ private List childs; //skip all getter/setter method } public class Child implements Serializable { /** identifier field */ private Long id; /** persistent field */ private net.foxlog.model.Parent parent; //skip all getter/setter method }
在我们查询Parent对象的时候,默认只有Parent的内容,并不包含childs的信息,如果在Parent.hbm.xml里设置lazy="false"的话才同时取出关联的所有childs内容.
问题是我既想要Hibernate默认的性能又想要临时的灵活性该怎么办? 这就是Fetch的功能。我们可以把fetch与lazy="true"的关系类比为事务当中的编程式事务与声明式事务,不太准确,但是大概是这个意思。
总值,fetch就是在代码这一层给你一个主动抓取得机会.
Parent parent = (Parent)hibernateTemplate.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { Query q = session.createQuery( "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有什么用”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。