论坛首页 Java版 Hibernate

鉴于反复出现讨论hibernate适用性问题的帖子,这次希望有个定论

浏览 35936 次
该帖已经被评为良好帖
作者 正文
最后更新时间:2007-12-15
根本没有必要过分OO

google shards这个项目文档看了一些, 主要着力点在透明的数据库partition, 而不是OO!
   
0 请登录后投票
最后更新时间:2008-08-29
hb,和sp是java衰亡的开始,hb和sp对java开发没有更多改观
不能很好的提高开发速度也不能提高性能,反而与此相反
只会用拗口的名词来骗客户让开发人员更早的死亡而已
所以我觉得这个坛子太过于宣言这2者,实在是罪过罪过
   
0 请登录后投票
最后更新时间:2007-12-16
引用
1、以数据库为中心建模 VS 以领域模型为中心建模:
   老开发人员大多倾向于前者,因为比较符合过去的开发习惯,另外他们强调数据库的生命周期大于App
   向我这样的只有几年工作经验的往往会倾向于后者,因为这能更充分发挥ORM的威力,更符合OO,免去很多维护DB的繁琐工作。

    领域建模距离实际应用还有距离,ORM达不到屏蔽关系模型、数据库实现的能力,在相当长一段时间内还是一数据建模为主。(参见rod johnson , j2ee design and development)
引用

2、Hibernate VS iBatis/JDBC:
   担心失去对SQL待控制权,导致不能做优化,DBA反对
   Hibernate是在JDBC之上的又一层框架,因此想当然的认为其性能不如iBatis/JDBC(我认为这个结论不成立,因为引入一个ORM层给了我们更多机会去优化性能,比如一二级缓存、lazyload、查询缓存,并且方式更优雅)。参考为什么ORM性能比iBATIS好?
   担心OpenSessionInView模式有性能问题(http://www.javaeye.com/topic/17501)
   Hibernate无法应付复杂查询(我认为这不是问题,HQL和criteria查询能力很强,再不济还可以用SQL啊)

3、对Hibernate等ORM框架能否胜任大型项目的怀疑:
   其实项目大小不是技术选型的主要考虑,关键看项目类型,OLTP还是OLAP、广而浅型的还是窄而深型的、数据量大小等等,这些因素更能影响结果

这两个问题总结下来是同一个问题,关键看项目类型,OLTP还是OLAP,ORM不适合做OLAP(参见同上)。
引用

4、Hibernate学习成本高
   不可否认,相对于spring、struts,Hibernate是一个学习曲线陡峭的框架,但是我觉得综合考虑开发效率和长期收益,还是值得学习和采用的

   对于一个项目来说,学习成本,如果每一个人都需要很深入的了解,是很大的成本,个人感觉一个Team有一个这样的就够了,其他人会用就好。
   个人来说,出来混,这点学习成本还是值得的。

分布式又是一个大话题,在恰当的时候总会有人把问题提高到分布式的层次上去考虑,耐人寻味。
   
0 请登录后投票
最后更新时间:2007-12-16
Qieqie 写道

4、使用Hibernate不需要大牛,只要不盲从,回到基本面,从reference开始。
不了解的,不踏实的,新碰到的,那就做做试验--磨刀不误砍柴功

先到此为止,算是对楼上部分观点的回复


把hibernate用好不见得是大牛,个人对大牛的理解就不必讨论了。
对于一个项目,如果用到hibernate,还是需要一个能够把握住的人,规避技术风险。把握不了的技术,还不如不用,弊大于利。
不知道Qieqie说要在项目里,从新手一点点来,还是在一定把握程度上一点点来,如果是后者就没什么说得了。
   
0 请登录后投票
最后更新时间:2007-12-16
coolnight 写道


根本没有必要过分OO

google shards这个项目文档看了一些, 主要着力点在透明的数据库partition, 而不是OO!


努力理解一下“过分OO”的含义,不太明白,如何为“过分OO”,
使用hibernate是过分OO么?那怎么样又不是呢?
请明确一下。
   
0 请登录后投票
最后更新时间:2007-12-16
robbin 写道
JavaEye网站的数据库设计是面向对象为中心的设计,但是拿三大范式来衡量,大部分设计都是吻合的,而我们的数据库缓存命中率在90%左右。缓存服务器的流量是数据库服务器流量的2.5倍之多。事实上我们有很多地方的查询尽量避免join,宁可让他n+1,这样速度反而更快,缓存命中率更高。


赞同,join让二级缓存成了摆设。二级缓存加上batch fetch,可以极大缓解n+1。
   
0 请登录后投票
最后更新时间:2007-12-16
说到访问数据库的性能问题,其实用不用ORM,或者用不用iBATIS,这些都是皮毛,甚至用不用缓存,怎么用缓存,也没有触及到本质问题,真正的本质在于“数据库的瓶颈在于访问数据库文件的磁盘IO,尽量减少数据库服务器的磁盘IO才能从本质上提高数据库吞吐量”。围绕这个本质,需要你从操作系统层面,数据库层面,应用程序的架构设计,缓存方式和应用程序框架方面进行通盘的考虑,至于说用不用Hibernate只是很小的一个战术层面而已。
   
0 请登录后投票
最后更新时间:2007-12-17
Godlikeme 写道
Qieqie 写道

4、使用Hibernate不需要大牛,只要不盲从,回到基本面,从reference开始。
不了解的,不踏实的,新碰到的,那就做做试验--磨刀不误砍柴功

先到此为止,算是对楼上部分观点的回复


把hibernate用好不见得是大牛,个人对大牛的理解就不必讨论了。
对于一个项目,如果用到hibernate,还是需要一个能够把握住的人,规避技术风险。把握不了的技术,还不如不用,弊大于利
不知道Qieqie说要在项目里,从新手一点点来,还是在一定把握程度上一点点来,如果是后者就没什么说得了。



新手:这个词不好定义,他可能知识很扎实,只是对hibernate比较陌生,如果是这样的话,还是可以使用hibernate的。

hibernate其基础理论是很明显的,所以是可以以一致思维贯彻地学习的,只要花一点时间,掌握它是完全有把握的。
(掌握它不需要天资多好,所以说不需要17大大大的牛)
认为其学习曲线较其它陡的,那是因为学校里没有这样的知识传授,书本里没有这样的知识传授导致的。之前没有这样的知识传授,这造成一些沟壑,但是不意味它很困难。

hiebrnate有哪些沟壑:
1、Session是本次使用到的持久对象的容器,并内在使用jdbc的connection派发sql
2、Session的生命周期,不同的应用可能有不同的策略,是一次数据操作一个Session,或一个用户请求共享同一个Session?
后者可能使用到了Open Session In View Filter/Interceptor.或hibernate3的sessionFactory.getCurrentSession()
3、对象与容器的几种关系,以及如何转化?同样Id的对象是否可以有多个copy在容器中?
4、session flush是什么意思,什么时候会(自动)flush
5、load或object的many-to-one可能会用到proxy,这是什么意思?lazy-loading与此有关。
6、hibernate对集合的理解和处理
7、hibernate对cascade的理解和处理
。。。


hibernate有哪些局限:1、session是一个容器,一次session装载过多object,会爆棚=>解决之道:evict, bulk operation
2、session总是装载一个对象的所有属性列,如果该属性数目够大(>50),会对性能有所影响=>解决之道:对类或表列进行适当分拆
3、session默认总是对持久对象建立snapshot,所以1个对象将占用2倍的空间。=>一般这个不造成问题,除非是以上 1 的情况
。。。

hibernate"奇怪"的地方:
1、save/perist一个对象时,为什么有的对象立即发送一个insert语句,有的不是:
这和主建策略有关,程序自己assign的主键,hibernate不会立即发送insert,其他的会

2、设置了join策略,但对query查询无效
对对象的某个to-one的属性设置join策略只load/get或nav到该对象时有效,query查询无效,哪怕该查询只返回一个对象。

3、修改对象时候,为什么抛出错误:
在Session的生命周期内,已经被Session管理的对象的数据库更新语句会自动被hibernate检测在必要的时候发送。
所以,程序没有必要调用dao.update/object.update(in active record pattern)的方法。如果调用了dao.update方法,则会抛出该错误。

4、那为什么同样的程序我调用就是错误,别人update就可以调用,而且必须调用才会更新到数据库?
那是因为“别人”的session周期很短,和“我自己”使用的Session周期策略不一样,他调用update时所使用的session已经不是前一句load/get/query该对象后的session。
也有可能是“别人”update的对象和刚才load/get/query出来的对象是同一个对象(==返回true),此时update方法是多余的,但是调用了也不会发生错误(update的意思是:将一个还没有被给定session管理的detached对象交给session管理,但是如果该对象本来已经被session管理了,session也不会抛出错误)
5、不想更新某个数据,但是hibernate却自动给我更新到数据库,真是想不到:
一个对象如果被Session管理(之前从session load/get/query出来或该对象被update到session后),如果该对象的属性变更了,这会被hibernate检测到,会自动被派发update sql,所以不要去更新他的值,如果本意不是要把“更新持久化”到数据库的话。
。。。

小心:
二级缓存 总是要特别的注意,这是一个大策略,不是API级别的决定。

以上观点均被本人实践过,也仅为片面摘要。
   
0 请登录后投票
最后更新时间:2007-12-17
引用

新手:这个词不好定义,他可能知识很扎实,只是对hibernate比较陌生,如果是这样的话,还是可以使用hibernate的。

hibernate其基础理论是很明显的,所以是可以以一致思维贯彻地学习的,只要花一点时间,掌握它是完全有把握的。
(掌握它不需要天资多好,所以说不需要17大大大的牛)
认为其学习曲线较其它陡的,那是因为学校里没有这样的知识传授,书本里没有这样的知识传授导致的。之前没有这样的知识传授,这造成一些沟壑,但是不意味它很困难。


没用过就是新手,没的说。

我的疑义在于在一个项目中如何规避技术风险。
不是说hibernate这个东西多么难理解,而是在项目中如何去把握。
技术都是说起来好听,用起来细节特别多,遇到问题解决问题不是
规避风险的好办法。

后面总结的很好,作项目基本够用了,但距离实际应用开发还缺乏很多细节。
   
0 请登录后投票
最后更新时间:2007-12-17
Godlikeme 写道


没用过就是新手,没的说。

我的疑义在于在一个项目中如何规避技术风险。
不是说hibernate这个东西多么难理解,而是在项目中如何去把握。
技术都是说起来好听,用起来细节特别多,遇到问题解决问题不是
规避风险的好办法。

后面总结的很好,作项目基本够用了,但距离实际应用开发还缺乏很多细节。


规避技术风险
规避技术风险,分两种情况:
1、知道技术风险在哪的
这好办,迎难而上,明知山有虎,偏向虎山行
做一个技术的基准测试,测试该风险是否可被克服。

2、不知道技术风险在哪的
那先不从某技术入手,而是从以下问题入手
1)为什么它成为候选?
答案可能是:成熟、开发简单、快捷维护、甚至是人云亦云

2)为什么它最后可被选?
(架构师需要)分析自己系统的特点,预测系统的关键业务用例,有挑战性的用例,用具体某个技术实现它看看
a、是否可实现
b、是否可被简单实现
c、是否满足其他的非功能要求-如性能、资源占用(内存)、稳定性、极限等

这一点的根据是:
关注应用于业务的技术,而非脱离业务的技术,一个技术如果能满足关键业务,基本上就具有了可行性。

如果大的方向把握好了,可行了,细节上应该是可以克服的(此时考验的是java基础知识了)。
落实到细节,需要不断动手了,就像做数学题,多练习,练习多了,自然会成仙。
使用hibernate很难全掌握了才用的(几乎不可能),只能在了解其基础原理上,关键点后,渐行渐知的

项目启动 之 技术宣贯
项目确认好使用某种技术后,需要做好开发前的技术宣贯,要结合样板代码,在团队中间取得共识:
1、为什么我们使用这个技术
2、这个技术的基础知识、API
3、以什么套路使用该技术
4、更多资料(ref)如何获得、如何使用
。。。
   
0 请登录后投票
论坛首页 Java版 Hibernate

跳转论坛:
JavaEye推荐