锁定老帖子 主题:hibernate开发总结
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-08-26
1、OpenSessionInView对系统的影响有多大没测试过,不过大家都说使用的时候一定要慎重。个人使用也比较少
2、既然用了hibernate, lazyload毫无疑问是一个很好的东西,否则是自找麻烦。但是lazy对性能的影响有大多不得而知。
3、hibernate默认会把所有字段都update一次,这个对效率当然是有影响的。 你可以试着写hql去update或者设置动态sql: 在update 的时候又选择的去save,但是动态sql对效率的提升有多大我也不太清楚。
4、个人觉得N+1不是问题,在有缓存的情况下效率和性能应该是很高的。 反而过多的关联查询性能不一定高/低多少,这样N+1不是什么坏事,何况在缓存的情况下根本就不会去查数据库。
5、要搞清楚为什么要用lazy和什么情况下用lazy,用和不用的区别、影响又在哪。不要一出问题就说什么把lazyload设置成EAGER之类的就当成是解决了问题了事。这类人完全没明白自己在干什么。
7、如果是openAmf这类遇到需要序列化的项目(lazyload不起作用),这个时候就别想着用什么lazy、EAGER和OpenSessionInView了 实体全部拆散,需要的时候自己再封装成一个对象里面去。回归原始。
8、既然没有lazyload就应该明白过多的对象关联是很恐怖的。 例如:User 里面有几个UserPorperty对象用来存储User的道具状态之类的。现在你只希望update status这一个字段在User user=get(User);的时候会把这些无用属性都查出来,因为:EAGER。 当然 你可以用几个办法解决:1、”update User set status = 1“。2、lazy 3、把User里面的UserProperty对象改为Integer :ID在需要的时候再去查询
9、开发效率和性能无法兼得。 最典型的例子就是hibernate会加载你“不需要”的东西出来。 例如:你想找出User 的status、age属性,在查询的时候会把整个User都加载出来。代码上是方便了许多,以后如果扩展也很方便,因为这里User的东西都有了随便你之后修改其他属性。 但是在这里千万别说Hibernate效率低,因为这是你选择的结果:如果你希望效率更高,整个系统的东西都应该是你定制的。 例如:你这里只想修改status =1 那么你就应该用hql:"update User set status = 1" 而不是User user=get(User); user.setStatus(1); save(user);
10、关于批量saveOrUpdate,这里我只用过隔20/30次save操作flush一次这种方式,还有拼接sql字符串的方式的效率会更高一些。 不要直接用hibernateTemplter提供的saveOrUpdateAll方法,对于大的数组会内存溢出,因为hibernate都是把session存在内存中
11、用HQL的语法大部分只用到了封装对象模式(我自己这样描述) 就像:"from User" 而是不 "select * from t_user"。如果需求是很复杂的场景hibernate还是提供了sql方式解决:createSQLQuery()
12、使用hibernate最理想的情况就是系统是用的时候就设计好了的,而且你应该明白设计之后的系统的利弊。 其中影响最大的就是实体之间的关系如何设定,lazyload openSessioninView是否能够派上用处。 一旦用不上思维就要变换了,最显著的地方就是不要把fetch 模式改为EAGER就了事,这样只会让你跑来发帖说hibernate效率如何之差
13、缓存那是一定要用的,使用简单效果明显。ehcache很好很强大。
14、 lazy+缓存 < 一个好的设计
个人在开发过程中遇到的最多问题大概就这些了,效率问题无非是体现在封装和load整个实体这2个方面。总要的是如果你想优化,空间还是有很多的。实在不行我们还有大绝招:createSQLQuery() !
欢迎大家来补充。提供更多的优化和解决办法。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-08-29
尽量避免List<User> userList=list(User.class); for(User user:userList){ do something.... update(user); } 这种操作的问题很明显,如果整个循环操作长达几分钟 那么用户操作在update之后会照成回档几分钟。 应该改为 List<Integer> list=list("select id from User"); for(Integer id:list){ User user=get("from User where id = "+id); do something.... update(user); } |
|
返回顶楼 | |
发表时间:2011-08-29
有几点学习了,谢谢!
|
|
返回顶楼 | |
发表时间:2011-08-29
在分析透彻业务的基础上,合理的利用ehcache,将缓存发挥到淋漓尽致。hibernate很好很强大
|
|
返回顶楼 | |
发表时间:2011-08-29
最要命的是merge有bug,没merge进去。
|
|
返回顶楼 | |
发表时间:2011-09-05
Hibernate进行大数据量处理时的优化操作
1) 在处理大数据量时,会有大量的数据缓冲保存在Session的一级缓存中,这缓存大太时会严重显示性能,所以在使用Hibernate处理大数据量的,可以使用session.clear()或者session. Evict(Object) 在处理过程中,清除全部的缓存或者清除某个对象。 2) 对大数据量查询时,慎用list()或者iterator()返回查询结果, 1. 使用List()返回结果时,Hibernate会所有查询结果初始化为持久化对象,结果集较大时,会占用很多的处理时间。 2. 而使用iterator()返回结果时,在每次调用iterator.next()返回对象并使用对象时,Hibernate才调用查询将对应的对象初始化,对于大数据量时,每调用一次查询都会花费较多的时间。当结果集较大,但是含有较大量相同的数据,或者结果集不是全部都会使用时,使用iterator()才有优势。 3. 对于大数据量,使用qry.scroll()可以得到较好的处理速度以及性能。而且直接对结果集向前向后滚动。 3) 对于关联操作,Hibernate虽然可以表达复杂的数据关系,但请慎用,使数据关系较为简单时会得到较好的效率,特别是较深层次的关联时,性能会很差。 4) 对含有关联的PO(持久化对象)时,若default-cascade="all"或者 “save-update”,新增PO时,请注意对PO中的集合的赋值操作,因为有可能使得多执行一次update操作。 5) 在一对多、多对一的关系中,使用延迟加载机制,会使不少的对象在使用时方会初始化,这样可使得节省内存空间以及减少数据库的负荷,而且若PO中的集合没有被使用时,就可减少互数据库的交互从而减少处理时间。 6) 对于大数据量新增、修改、删除操作或者是对大数据量的查询,与数据库的交互次数是决定处理时间的最重要因素,减少交互的次数是提升效率的最好途径,所以在开发过程中,请将show_sql设置为true,深入了解Hibernate的处理过程,尝试不同的方式,可以使得效率提升。 7) Hibernate是以JDBC为基础,但是Hibernate是对JDBC的优化,其中使用Hibernate的缓冲机制会使性能提升,如使用二级缓存以及查询缓存,若命中率较高明,性能会是到大幅提升。 8) Hibernate可以通过设置hibernate.jdbc.fetch_size,hibernate.jdbc.batch_size等属性,对Hibernate进行优化。 |
|
返回顶楼 | |
发表时间:2011-09-09
不要直接用hibernateTemplter提供的saveOrUpdateAll方法,对于大的数组会内存溢出,因为hibernate都是把session存在内存中
??? 会产生很多session吗?不就一个吗? |
|
返回顶楼 | |
发表时间:2011-09-13
447214075 写道 不要直接用hibernateTemplter提供的saveOrUpdateAll方法,对于大的数组会内存溢出,因为hibernate都是把session存在内存中
??? 会产生很多session吗?不就一个吗? session不会产生很多个。笔误,只是session在处理集合的时候会先缓存在内存中。(一级缓存?) 而且saveOrUpdateAll方法本身没有什么稀奇的。只是一个for循环saveOrUpdate 。 |
|
返回顶楼 | |
发表时间:2011-10-25
5、要搞清楚为什么要用lazy和什么情况下用lazy,用和不用的区别、影响又在哪。不要一出问题就说什么把lazyload设置成EAGER之类的就当成是解决了问题了事。这类人完全没明白自己在干什么。
这点能清楚解释下不?用和不用的区别、影响又在哪? |
|
返回顶楼 | |
浏览 6500 次