鉴于反复出现讨论hibernate适用性问题的帖子,这次希望有个定论
也不仅仅是hibernate一个框架的问题了,其实可以上升到O/R Mapping的应用策略问题
几乎每隔几周就会出现类似的讨论,比如 主题: 有没有Hibernate的成功大型项目实现?、Hibernate,憋脚的ORM框架
这说明这个问题还是很有讨论的必要。
过去的几次比较热烈的讨论我基本都看了,焦点主要集中在这几个方面:
1、以数据库为中心建模 VS 以领域模型为中心建模:
老开发人员大多倾向于前者,因为比较符合过去的开发习惯,另外他们强调数据库的生命周期大于App
向我这样的只有几年工作经验的往往会倾向于后者,因为这能更充分发挥ORM的威力,更符合OO,免去很多维护DB的繁琐工作。
2、Hibernate VS iBatis/JDBC:
担心失去对SQL待控制权,导致不能做优化,DBA反对
Hibernate是在JDBC之上的又一层框架,因此想当然的认为其性能不如iBatis/JDBC(我认为这个结论不成立,因为引入一个ORM层给了我们更多机会去优化性能,比如一二级缓存、lazyload、查询缓存,并且方式更优雅)。参考为什么ORM性能比iBATIS好?
担心OpenSessionInView模式有性能问题(http://www.iteye.com/topic/17501)
Hibernate无法应付复杂查询(我认为这不是问题,HQL和criteria查询能力很强,再不济还可以用SQL啊)
3、对Hibernate等ORM框架能否胜任大型项目的怀疑:
其实项目大小不是技术选型的主要考虑,关键看项目类型,OLTP还是OLAP、广而浅型的还是窄而深型的、数据量大小等等,这些因素更能影响结果
4、Hibernate学习成本高
不可否认,相对于spring、struts,Hibernate是一个学习曲线陡峭的框架,但是我觉得综合考虑开发效率和长期收益,还是值得学习和采用的
其实有一个事实被很多人忽略了——Hibernate只是对JDBC的一个封装,因此它可以跟iBatis/JDBC在同一个项目中并存,就好比突击步枪和狙击步枪的关系,两者都有存在的价值和适用场合,不能互相取代。
但是,显然突击步枪是大量装备的通用武器,而狙击步枪是少量装备的特种武器
参考帖子:
OpenSessionInView会不会影响性能?
选择Hibernate还是iBatis?
选择Hibernate还是iBatis?
我为什么选择 iBatis 而不是 Hibernate(对于正在选型的人的建议)
Hibernate,憋脚的ORM框架
对迷茫于Hibernate/JPA的人提一些建议。
为什么ORM性能比iBATIS好?select s.guid, ROWNUM as rowno from student_base_info s join resume r on s.guid=r.stu_guid where r.resumetime > to_date('2007-12-01','yyyy-mm-dd') AND rowno between 10000 and 10010
rownum不能直接进行<比较吧?需要用内嵌表。 93 楼 bulargy 2007-12-28 robbin 写道
我仔细看了一遍你贴出来的执行计划,终于发现你关联查询慢的根源了!请看:
s.guid=r.stu_guid
你的关联查询关联外键上面根本就没有建立索引!这种关联查询会造成你的student表和resume表全表扫描,难怪会这么慢!
给student表的guid字段建立索引,然后给resume表的stu_guid字段也建立索引,再查询一遍,我保管你1秒钟查询完毕
期待firmgoal 的实际测试结果~~~~ 94 楼 firmgoal 2007-12-28 bulargy 写道robbin 写道
我仔细看了一遍你贴出来的执行计划,终于发现你关联查询慢的根源了!请看:
s.guid=r.stu_guid
你的关联查询关联外键上面根本就没有建立索引!这种关联查询会造成你的student表和resume表全表扫描,难怪会这么慢!
给student表的guid字段建立索引,然后给resume表的stu_guid字段也建立索引,再查询一遍,我保管你1秒钟查询完毕
期待firmgoal 的实际测试结果~~~~
我上面已经答复了啊,测试的时候就是已经有外键索引了。 95 楼 jasongreen 2008-01-09 timerri 写道我有几个预言......
1.orm工具将被oodb取代.....
2.数据库索引和数据将被分开处理
3.分布式数据将成为应用主流...
jdbc,iBATIS,hibernate真的有本质区别么?扳手和活动扳手的区别罢了.....当然,你也可以选择用钳子...
赞一个,第一条我认同 96 楼 JavaDivinity 2008-01-10 收藏在哪里...没看完呢..要收藏起来..值得学习呀. 97 楼 AK_47 2008-01-10 HIBERNATE有一些用法是不支持的
例如
1 左连接或右连接的时候,你只能连接它的子集(如果当初没有建立连接的话...)
2 部分COUNT无法计算,例如我查询某一个条件的条数,并且去处重复了,这个时候再统计数据就比较麻烦了
3 某些关联的查询在SQL里没有问题,但是同样或者类似的写法在HQL里就无法使用
所以我觉得如果不是有牛人作为技术支持的话,HIBERNATE最后不要用在大项目里,遇到越复杂的逻辑HIBERNATE用起来就越难以使用 98 楼 jwd001 2008-01-12 对于firmgoal的问题,我觉得可以直接在resume表上建标志字段,比如对行业参数加个industry char(30),(假设有30个行业选择),或用整型数的bit位表示,这样就没有关联表了.查询就用全索引扫描. 99 楼 jwd001 2008-01-12 另外,原先之所以有多个关联表,而不是像robbin那样设计只有一个,可能出于以下原因:如果一个resume选择4个地区,3个行业,3个职位,那么一个关联表的就有4*3*3=36条记录,而多个关联表则只有4+3+3=10条记录 100 楼 Aaron_Zhang 2008-01-14 Qieqie 写道1、hibernate没有什么是“意料之外”的故事,一切都显得理所当然,若有意外,那应该归功于盲从,而非被盲从的对象。
2、使用hibernate,我不用去“SQL 跟踪、优化”,看几眼,感觉一下就够了。优化也轮不到SQL,更多的是你的数据库策略上的非SQL层级的优化(比如索引)。SQL没什么好优化的,少读几个列? 没必要;表连接少一点?(不用看SQL,看Hibernte就可以看出来).
3、使用自写的SQL,那就真需要“SQL跟踪”了,你不知道你哪一个地方写错了,这够没意义,而且够烦。
4、使用Hibernate不需要大牛,只要不盲从,回到基本面,从reference开始。
不了解的,不踏实的,新碰到的,那就做做试验--磨刀不误砍柴功。
先到此为止,算是对楼上部分观点的回复
说的不错 101 楼 gavin213 2008-01-15 受教了,LZ说的很透彻,以前这种贴都快看烂了..... 102 楼 dabb 2008-01-15 按个人经验,使用hibernate碰到的最讨厌的事情:
1.需要在设计模型时就需要考虑lazy load的问题
2.是否动态update,也需要在设计模型时作点考虑
当然上面的“问题”也不能算作问题,只是个人更倾向于将这些细节问题留到开发具体应用功能点的时候去考虑。特别是模型设计者和功能开发人员分开的时候,从职责上看这些问题更应该归到功能开发人员的责任上。设计模型时考虑这些问题,套句xp常用语,有点“过度设计”。
而jdbc(or ibatis)不存在该问题。所以现在的开发中我更倾向于使用jdbc方式的相对于 hb(或则其它orm,jdo等)更轻的持久层解决方案。 103 楼 dabb 2008-01-15 按个人经验,使用hibernate碰到的最讨厌的事情:
1.需要在设计模型时就需要考虑lazy load的问题
2.是否动态update,也需要在设计模型时作点考虑
当然上面的“问题”也不能算作问题,只是个人更倾向于将这些细节问题留到开发具体应用功能点的时候去考虑。特别是模型设计者和功能开发人员分开的时候,从职责上看这些问题更应该归到功能开发人员的责任上。设计模型时考虑这些问题,套句xp常用语,有点“过度设计”。
而jdbc(or ibatis)不存在该问题。所以现在的开发中我更倾向于使用jdbc方式的相对于 hb(或则其它orm,jdo等)更轻的持久层解决方案。 104 楼 dabb 2008-01-15 另外,个人认为orm层在应用系统的整体架构里属于比较次要的部分,大部分情况下采用orm并不能提高多少生产效率,架构设计人员没有必要在该问题上纠缠不清。是否采用hb充其量只能算是架构设计人员和开发人员的个人喜好而已,无关大局。 105 楼 jackzhangyunjie 2008-01-17 各位都写的太好啦,让我受益很多,谢谢
106 楼 Ab.Yann 2008-04-28 ray_linn 写道就一点就够让人讨厌了,hibernate天生就是贫血
是不是贫血,就看你向里面充多少血了,hibernate除了getter,setter方法外,对基于的方法都是透明的. 107 楼 ynztpwl 2011-08-17 LZ你好,针对3.1中的问题说下自己的看法哈。hibernate可以选择性的列出需要的字段,使用HQL或则SQL都是可以的(语法都差不多举个例子:select s.id,s.name from Student(实体类) as s where ...) 他返回一个List<Object[]> 数组中下表为0的装id字段,为一的装name字段。
另外Hibernate是可以对字段进行懒加载的字段进行懒加载的,只是这个需要类增强工具,修改字节码,生成代理,达到懒加载的目的。(这个可能就没意义了哈) 108 楼 ynztpwl 2011-08-17 LZ你好,针对3.1中的问题说下自己的看法哈。hibernate可以选择性的列出需要的字段,使用HQL或则SQL都是可以的(语法都差不多举个例子:select s.id,s.name from Student(实体类) as s where ...) 他返回一个List<Object[]> 数组中下表为0的装id字段,为一的装name字段。
另外Hibernate是可以对字段进行懒加载的字段进行懒加载的,只是这个需要类增强工具,修改字节码,生成代理,达到懒加载的目的。(这个可能就没意义了哈)[size=x-small][/size]