论坛首页 Java企业应用论坛

谈谈Hibernate令人不爽的地方

浏览 95782 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2006-09-14  
对于Hibernate,有两点值得反思:

1、HQL创造出来一种语言,目的是以对象方式类SQL去查询数据库,但是为什么不像rails那样,干脆直接定义COC让数据库schema 和对象的schema吻合在一起呢?这样,SQL不就是直接变成了对象查询语言了吗?缺点就是放弃更多更复杂的对象映射模型。但是我的经验表明,项目中要尽量避免复杂的对象映射,这样性能很糟糕,也很容易出错,实际上我仅仅只用n:1就可以表达很多种映射模型了。化繁为简,大巧若拙实为最高境界。

2、现在极其厌恶Hibernate生成的SQL,又臭又长,极难阅读。
   发表时间:2006-09-14  
1.我想hql的出现是为了屏蔽数据库之间sql的差异,也就是为了跨数据库。如果你直接写sql的话,难保会写一些native sql.(虽然一般我们也不会轻易换数据库)

2.估计hibernate不赞成你老阅读它的sql,哈哈。(是够长够臭)
0 请登录后投票
   发表时间:2006-09-14  
Hibernate在查询时,面对很多映射有时候显得很苍白。

例如有个业务场景,Department和Employee是一对多关系。现在我对Department进行分页查询,要求在显示的页面上同时显示每个Department中Employee的数量。这是一个很简单的业务场景,但是想象一下如何用hibernate进行映射?

首先否定一种做法:hql:FROM Department department。然后针对每个department,去做department.getEmployees().size()。这样不仅会发送n+1条SQL,而且性能太低。

我们肯定希望采用一句HQL解决问题,但是此时问题来了,当你试图做SELECT department, count(employee.id) FROM .....这样的HQL时,在Java端,发现没有一个合适的对象可以映射。

从OO的角度,其实可以在Department这个类中加一个employeeSize来表示这种业务场景。但是好像Hibernate无法去做类似的映射。而iBatis在这个方面却灵活的多。
1 请登录后投票
   发表时间:2006-09-14  
碰到统计的话,hibernate不如jdbc甚至
我没用过ibatis,估计以后会看看
0 请登录后投票
   发表时间:2006-09-14  
robbin 写道
2、现在极其厌恶Hibernate生成的SQL,又臭又长,极难阅读。
深有同感!
原因是要为表生成别名,还要为字段生成别名,而且当 SQL 只涉及到一张表的时候还要为表生成一个别名 this_,为每个字段生成别名 *_0_,浪费!
对了,那位热心人能将这个问题提交给 Hibernate 开发组试试看!
0 请登录后投票
   发表时间:2006-09-14  
Ibatis,爽就一个字。
0 请登录后投票
   发表时间:2006-09-14  

EQL, HQL, OQL这些QL的阻碍作用大于积极意义。
有一点积极意义,某些情况下简化了SQL。
比如,HQL
from Topic where user.resigertedTime > ...

对应的SQL
select topic.* from topic, user
where topic.user_id = user.id and user.resigertedTime

这种关联越深,SQL的层次就越深,甚至需要Nested Sub Query.
这个时候HQL, EQL的意义就越明显。
不过这类QL应该作为辅助工具使用,而不是强制在整个应用程序使用。

RelationAST relation = parseHQL( simpleHQL);
// do any thing you like with the HQL
String complexSQL = relation.toSQL();
//execute SQL.
0 请登录后投票
   发表时间:2006-09-14  
robbin 写道
对于Hibernate,有两点值得反思:

1、...但是我的经验表明,项目中要尽量避免复杂的对象映射,这样性能很糟糕,也很容易出错,实际上我仅仅只用n:1就可以表达很多种映射模型了...
...


复杂的对象映射,源自企图用一个优美的object graph,在各层来表达实体关系。让一个业务方法返回一个Domain Entity比返回一个map, array好看得多。

downpour 写道

我们肯定希望采用一句HQL解决问题,但是此时问题来了,当你试图做SELECT department, count(employee.id) FROM .....这样的HQL时,在Java端,发现没有一个合适的对象可以映射。


比如这个,最省力的方法就是返回一个array 好了。虽然看上去不那么OO。
0 请登录后投票
   发表时间:2006-09-14  
那robbin说说应该用哪个呢
0 请登录后投票
   发表时间:2006-09-14  
我现在觉得还是jdbc来的最直接,有什么问题无非就是调试一下sql语句。虽然有时候象是在干体力活,但是多花一分钟的时间写sql语句总比花一个小时去研究hibernate产生的奇奇怪怪的现象要划算。

我把potian举过的例子修改下,假设你对性能感兴趣:
那么通常下hibernate会批量更新,但是A情况下就不会,A情况下如果满足B条件,它又能批量更新,不过你不能用C功能,否则它又不行,你是不是很崩溃?最后你可能要花好几个小时终于弄清楚了这个小问题,那边用jdbc做事的早就做完了。

jdbc大家都会,所以相对于整个团队而言,jdbc程序的可读性很好。而hibernate这种东西太复杂,每个人的掌握程度都不一样。这样,当我阅读或者修改别人的hibernate代码的时候,如果他用到了我不熟悉的功能,那么我总是要先花时间了解一下这个功能,否则当我操作对象的时候,不知道hibernate在后面做了些什么奇奇怪怪的事情,心里太没底。或许你是高手,可是当团队里别人要修改你的程序的时候,他怎么办呢?

用最简单的方式解决问题,是很有道理的。

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics