谈一下Hibernate令人不爽的地方
谈谈Hibernate令人不爽的地方
对于Hibernate,有两点值得反思:
1、HQL创造出来一种语言,目的是以对象方式类SQL去查询数据库,但是为什么不像rails那样,干脆直接定义COC让数据库schema 和对象的schema吻合在一起呢?这样,SQL不就是直接变成了对象查询语言了吗?缺点就是放弃更多更复杂的对象映射模型。但是我的经验表明,项目中要尽量避免复杂的对象映射,这样性能很糟糕,也很容易出错,实际上我仅仅只用n:1就可以表达很多种映射模型了。化繁为简,大巧若拙实为最高境界。
2、现在极其厌恶Hibernate生成的SQL,又臭又长,极难阅读。
跨数据库。。。未免是得不偿失。
这种场景很有可能是坐家里拍脑袋想出来的,大部分应用都是基于一种数据库。
严重同意,其实没必要将空数据写入数据库,一般很少将数据库中的数据更新为空,这是很不好的设计
意思是如果在更新时有的字段没有更新就没必要对它的字段进行更新?
可以通过在映射表里加入:
来实现的。
我们肯定希望采用一句HQL解决问题,但是此时问题来了,当你试图做SELECT department, count(employee.id) FROM .....这样的HQL时,在Java端,发现没有一个合适的对象可以映射。
从OO的角度,其实可以在Department这个类中加一个employeeSize来表示这种业务场景。但是好像Hibernate无法去做类似的映射。而iBatis在这个方面却灵活的多。
给一个构建函数:
public class Department(Department d, Integer employeeSize)
然后写成这样:
SELECT new Department(department, count(employee.id)) FROM .....
不就OK了吗?
我尝试过这种做法,不过记得好像以前调试的时候Hibernate报错啊。啥时候再调一把。
不过如果类似的业务场景中,我总觉得用构造函数不是一个很好的做法。因为可能一个构造函数只能满足单一的业务场景,如果现在再来一个类似的业务场景,这个构造函数就无能为力了。
现在有什么好的办法解决没有?
我现在也碰到了这个问题,一个代表团Team里面有多个公司Company(companySet),一个company对应一个用户User,一个User里又有多个人Person(personSet)。
现在页面要做team列表处理,每一个team的信息里包含company数量,person数量,以前在页面直接用companySet、personSet来实现,速度吓死人。
比如删除数据,竟然要先查询出来 设计这样一个方法不就行了的
session.delete(Class.class,id);??
上面这样类似的方法完全可以自己写
hibernate的二级缓存可不是你说的这样只保存id,看来你没有完全用好hibernate,
我的看法是凡是完全否定hibernate的,统统都是不会用hibernate的人。
hibernate是有缺点,但决不是你们嘴上说的那些,还有人说hibernate性能有问题,那也得看用在什么地方,怎么用,given king也说了hibernate适用于95%的需求,另外5%需要程序员自己解决的。凡是一棍子打死hibernate的人应该再去认真的学习学习hibernate
比如删除数据,竟然要先查询出来 设计这样一个方法不就行了的
session.delete(Class.class,id);??
上面这样类似的方法完全可以自己写
hibernate的二级缓存可不是你说的这样只保存id,看来你没有完全用好hibernate,
我的看法是凡是完全否定hibernate的,统统都是不会用hibernate的人。
hibernate是有缺点,但决不是你们嘴上说的那些,还有人说hibernate性能有问题,那也得看用在什么地方,怎么用,given king也说了hibernate适用于95%的需求,另外5%需要程序员自己解决的。凡是一棍子打死hibernate的人应该再去认真的学习学习hibernate
同意,hibernate确实有很多缺点,比如不够灵活,性能不够好。但只要它的优点能够满足我的需求我就会用它。
谁告诉你们用hibernate就要靠它包打天下了。
可以用hql一句话写:
select new DepartmentView(d.poin,count(e.poin)) from Department d inner join d.employeeSet group by d.poin.
这种快感是那些“一个项目就是一个公司”模式下搞开发的同僚们无法体会的。
很明显,你的感觉错了……
采用Hibernate和Spring之类开源项目的“关键应用”已经为数不少了,许多非常复杂的应用程序也都运用到了它们。
在使用hibernate的时候不要总是想着100%的hibernate,不要为了用hibernate而是使用hibernate,要有选择的使用JDBC,这才是理智的………………
很明显,你的感觉错了……
采用Hibernate和Spring之类开源项目的“关键应用”已经为数不少了,许多非常复杂的应用程序也都运用到了它们。
有哪一些你口中的<關鍵應用>呢?
可以舉幾個出來聽聽好嗎.
我只認為, 多狗餘的東西就是hibernate.
沒工作過的人才會想hibernate 能怎樣, 實際上並不能怎樣.
業務需求整天都在變, 一天變三次是件平常的事. 加field, 減field, 改field attribute 更可能
是不定期發生. 改這些東西, jdbc 只要改sql 和db, hibernate 呢?
跨平台的sql, 要寫出來有這麼難嗎? 還是你還在用沒subquery 的mysql?
我们项目中也有这个问题,不过我们是通过那个 createFilter来解决的
我们项目中也有这个问题,不过我们是通过那个 createFilter来解决的
————————————————————————————————————————
createFilter?可以具体谈谈?
我们肯定希望采用一句HQL解决问题,但是此时问题来了,当你试图做SELECT department, count(employee.id) FROM .....这样的HQL时,在Java端,发现没有一个合适的对象可以映射。
从OO的角度,其实可以在Department这个类中加一个employeeSize来表示这种业务场景。但是好像Hibernate无法去做类似的映射。而iBatis在这个方面却灵活的多。
给一个构建函数:
public class Department(Department d, Integer employeeSize)
然后写成这样:
SELECT new Department(department, count(employee.id)) FROM .....
不就OK了吗?
该方法总会报空指针异常: NullPointerException
对于Hibernate,有两点值得反思:
1、HQL创造出来一种语言,目的是以对象方式类SQL去查询数据库,但是为什么不像rails那样,干脆直接定义COC让数据库schema 和对象的schema吻合在一起呢?这样,SQL不就是直接变成了对象查询语言了吗?缺点就是放弃更多更复杂的对象映射模型。但是我的经验表明,项目中要尽量避免复杂的对象映射,这样性能很糟糕,也很容易出错,实际上我仅仅只用n:1就可以表达很多种映射模型了。化繁为简,大巧若拙实为最高境界。
2、现在极其厌恶Hibernate生成的SQL,又臭又长,极难阅读。
73 楼
ray_linn
2006-12-26
dogstar 写道
1.我想hql的出现是为了屏蔽数据库之间sql的差异,也就是为了跨数据库。如果你直接写sql的话,难保会写一些native sql.(虽然一般我们也不会轻易换数据库)
2.估计hibernate不赞成你老阅读它的sql,哈哈。(是够长够臭)
2.估计hibernate不赞成你老阅读它的sql,哈哈。(是够长够臭)
跨数据库。。。未免是得不偿失。
74 楼
ray_linn
2006-12-26
Readonly 写道
偶严重反对robbin对于HSQL的看法,如果没有HSQL的话,让偶回到过去那种写一个产品,要在N种数据库上调试不同的SQL兼容性,简直是噩梦啊。
COC就更没有啥话好说了,你完全可以给Hibernate加个COC plugin,只支持native PK,只支持1:N,只支持字段和数据库栏位同名。批评Hibernate不够自动化,就象批评手自一体的BMW比自动挡的KIA难用一样好笑...
Hibernate生成的SQL倒是没有啥感觉,因为基本上hibernate.show_sql都是false,只有很特殊的调试情况下,才需要打开这个参数去看生成的sql是怎么样的吧?
COC就更没有啥话好说了,你完全可以给Hibernate加个COC plugin,只支持native PK,只支持1:N,只支持字段和数据库栏位同名。批评Hibernate不够自动化,就象批评手自一体的BMW比自动挡的KIA难用一样好笑...
Hibernate生成的SQL倒是没有啥感觉,因为基本上hibernate.show_sql都是false,只有很特殊的调试情况下,才需要打开这个参数去看生成的sql是怎么样的吧?
这种场景很有可能是坐家里拍脑袋想出来的,大部分应用都是基于一种数据库。
75 楼
firedragon
2006-12-26
1,save(Foo f);不能通过f对象往里面传递哪些字段更新、哪些不更新;
严重同意,其实没必要将空数据写入数据库,一般很少将数据库中的数据更新为空,这是很不好的设计
cznc 写道
意思是如果在更新时有的字段没有更新就没必要对它的字段进行更新?
可以通过在映射表里加入:
dynamic-insert="true" dynamic-update="true"
来实现的。
76 楼
firedragon
2006-12-26
downpour 写道
Readonly 写道
downpour 写道
我们肯定希望采用一句HQL解决问题,但是此时问题来了,当你试图做SELECT department, count(employee.id) FROM .....这样的HQL时,在Java端,发现没有一个合适的对象可以映射。
从OO的角度,其实可以在Department这个类中加一个employeeSize来表示这种业务场景。但是好像Hibernate无法去做类似的映射。而iBatis在这个方面却灵活的多。
给一个构建函数:
public class Department(Department d, Integer employeeSize)
然后写成这样:
SELECT new Department(department, count(employee.id)) FROM .....
不就OK了吗?
我尝试过这种做法,不过记得好像以前调试的时候Hibernate报错啊。啥时候再调一把。
不过如果类似的业务场景中,我总觉得用构造函数不是一个很好的做法。因为可能一个构造函数只能满足单一的业务场景,如果现在再来一个类似的业务场景,这个构造函数就无能为力了。
现在有什么好的办法解决没有?
我现在也碰到了这个问题,一个代表团Team里面有多个公司Company(companySet),一个company对应一个用户User,一个User里又有多个人Person(personSet)。
现在页面要做team列表处理,每一个team的信息里包含company数量,person数量,以前在页面直接用companySet、personSet来实现,速度吓死人。
77 楼
ahuaxuan
2006-12-26
smilerain 写道
我现在感觉和robbin差不多,Hibernate 性能太低了.
HQL发明得也不台好.
比如删除数据,竟然要先查询出来 设计这样一个方法不就行了的
session.delete(Class.class,id);
get都会做,真么就不会做删除,还有修改...
Hibernate 的二级缓存简直是垃圾.保存个ID有什么用.
用的时候又要查,和没缓存一样的效果.
最后发现还是spring 的缓存拦截器好用.
唯一的优点,可以跨数据库.
HQL发明得也不台好.
比如删除数据,竟然要先查询出来 设计这样一个方法不就行了的
session.delete(Class.class,id);
get都会做,真么就不会做删除,还有修改...
Hibernate 的二级缓存简直是垃圾.保存个ID有什么用.
用的时候又要查,和没缓存一样的效果.
最后发现还是spring 的缓存拦截器好用.
唯一的优点,可以跨数据库.
比如删除数据,竟然要先查询出来 设计这样一个方法不就行了的
session.delete(Class.class,id);??
上面这样类似的方法完全可以自己写
hibernate的二级缓存可不是你说的这样只保存id,看来你没有完全用好hibernate,
我的看法是凡是完全否定hibernate的,统统都是不会用hibernate的人。
hibernate是有缺点,但决不是你们嘴上说的那些,还有人说hibernate性能有问题,那也得看用在什么地方,怎么用,given king也说了hibernate适用于95%的需求,另外5%需要程序员自己解决的。凡是一棍子打死hibernate的人应该再去认真的学习学习hibernate
78 楼
netfishx
2006-12-26
ahuaxuan 写道
smilerain 写道
我现在感觉和robbin差不多,Hibernate 性能太低了.
HQL发明得也不台好.
比如删除数据,竟然要先查询出来 设计这样一个方法不就行了的
session.delete(Class.class,id);
get都会做,真么就不会做删除,还有修改...
Hibernate 的二级缓存简直是垃圾.保存个ID有什么用.
用的时候又要查,和没缓存一样的效果.
最后发现还是spring 的缓存拦截器好用.
唯一的优点,可以跨数据库.
HQL发明得也不台好.
比如删除数据,竟然要先查询出来 设计这样一个方法不就行了的
session.delete(Class.class,id);
get都会做,真么就不会做删除,还有修改...
Hibernate 的二级缓存简直是垃圾.保存个ID有什么用.
用的时候又要查,和没缓存一样的效果.
最后发现还是spring 的缓存拦截器好用.
唯一的优点,可以跨数据库.
比如删除数据,竟然要先查询出来 设计这样一个方法不就行了的
session.delete(Class.class,id);??
上面这样类似的方法完全可以自己写
hibernate的二级缓存可不是你说的这样只保存id,看来你没有完全用好hibernate,
我的看法是凡是完全否定hibernate的,统统都是不会用hibernate的人。
hibernate是有缺点,但决不是你们嘴上说的那些,还有人说hibernate性能有问题,那也得看用在什么地方,怎么用,given king也说了hibernate适用于95%的需求,另外5%需要程序员自己解决的。凡是一棍子打死hibernate的人应该再去认真的学习学习hibernate
同意,hibernate确实有很多缺点,比如不够灵活,性能不够好。但只要它的优点能够满足我的需求我就会用它。
谁告诉你们用hibernate就要靠它包打天下了。
79 楼
suyejun
2006-12-26
downpour 写道
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在这个方面却灵活的多。
例如有个业务场景,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在这个方面却灵活的多。
可以用hql一句话写:
select new DepartmentView(d.poin,count(e.poin)) from Department d inner join d.employeeSet group by d.poin.
80 楼
together
2006-12-26
至少在中小规模的应用上,hibernate的性能还是非常不错的。至于某些特殊场合下,诸如需要在列表里显示某个部门的总员工数的,特殊处理一下也可以解决。
真正体会到hb带来的好处的,就是跨数据库!对于产品来讲,跨数据库是必须的,以针对不同目标客户选用不同的数据库。我现在就可以说,俺们的产品部署在任何HB支持的数据库上都没问题。
真正体会到hb带来的好处的,就是跨数据库!对于产品来讲,跨数据库是必须的,以针对不同目标客户选用不同的数据库。我现在就可以说,俺们的产品部署在任何HB支持的数据库上都没问题。
81 楼
Allen
2006-12-26
together 写道
至少在中小规模的应用上,hibernate的性能还是非常不错的。至于某些特殊场合下,诸如需要在列表里显示某个部门的总员工数的,特殊处理一下也可以解决。
真正体会到hb带来的好处的,就是跨数据库!对于产品来讲,跨数据库是必须的,以针对不同目标客户选用不同的数据库。我现在就可以说,俺们的产品部署在任何HB支持的数据库上都没问题。
真正体会到hb带来的好处的,就是跨数据库!对于产品来讲,跨数据库是必须的,以针对不同目标客户选用不同的数据库。我现在就可以说,俺们的产品部署在任何HB支持的数据库上都没问题。
这种快感是那些“一个项目就是一个公司”模式下搞开发的同僚们无法体会的。
82 楼
ken1984
2006-12-28
我感觉现在用这些的就是做做数据的管理平台,甚至是普通的所谓B/S系统的网站,论坛。就好像是把VB从C/S转到B/S,任何一个智力超过10的人都可以做。你们公司接单,做产品,然后收钱,这类公司最需要的就是快速,简单但又要让用户看起来很高档的东西。
83 楼
Allen
2006-12-28
ken1984 写道
我感觉现在用这些的就是做做数据的管理平台,甚至是普通的所谓B/S系统的网站,论坛。就好像是把VB从C/S转到B/S,任何一个智力超过10的人都可以做。你们公司接单,做产品,然后收钱,这类公司最需要的就是快速,简单但又要让用户看起来很高档的东西。
很明显,你的感觉错了……
采用Hibernate和Spring之类开源项目的“关键应用”已经为数不少了,许多非常复杂的应用程序也都运用到了它们。
84 楼
shiwentao1982
2007-06-01
我以前参与的一个项目,hibernate使用不当的话会有很严重的性能问题。所以在使用的时候还是应该谨慎啊。
85 楼
anweixiao
2007-06-01
wubg 写道
做报表时,用Hibernate生成一个复杂的SQL语句,真是煞费心思,左连右连痛苦,后面就只能直接用JDBC来实现,用hibernate实现对象add,update,delete是容易,但是,复杂的业务,就没法容易实现了
在使用hibernate的时候不要总是想着100%的hibernate,不要为了用hibernate而是使用hibernate,要有选择的使用JDBC,这才是理智的………………
86 楼
Lordaeron
2007-06-02
Allen 写道
ken1984 写道
我感觉现在用这些的就是做做数据的管理平台,甚至是普通的所谓B/S系统的网站,论坛。就好像是把VB从C/S转到B/S,任何一个智力超过10的人都可以做。你们公司接单,做产品,然后收钱,这类公司最需要的就是快速,简单但又要让用户看起来很高档的东西。
很明显,你的感觉错了……
采用Hibernate和Spring之类开源项目的“关键应用”已经为数不少了,许多非常复杂的应用程序也都运用到了它们。
有哪一些你口中的<關鍵應用>呢?
可以舉幾個出來聽聽好嗎.
我只認為, 多狗餘的東西就是hibernate.
沒工作過的人才會想hibernate 能怎樣, 實際上並不能怎樣.
業務需求整天都在變, 一天變三次是件平常的事. 加field, 減field, 改field attribute 更可能
是不定期發生. 改這些東西, jdbc 只要改sql 和db, hibernate 呢?
跨平台的sql, 要寫出來有這麼難嗎? 還是你還在用沒subquery 的mysql?
87 楼
chenkan2000
2007-07-25
我怎么觉得Hibernate用起来挺爽的。要求太低?农民啊。
88 楼
cm4ever
2007-07-31
不能延迟加载,一次性加载全部配置费时,哪个业务项目没有100个以上的表?单元测试时能烦死人。
由于人懒和工作忙,我也就改了hb2,没改hb3,麻烦。
其他的没了。
由于人懒和工作忙,我也就改了hb2,没改hb3,麻烦。
其他的没了。
89 楼
myyate
2007-07-31
downpour 写道
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在这个方面却灵活的多。
例如有个业务场景,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在这个方面却灵活的多。
我们项目中也有这个问题,不过我们是通过那个 createFilter来解决的
90 楼
Joseph
2007-07-31
myyate 写道
downpour 写道
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在这个方面却灵活的多。
例如有个业务场景,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在这个方面却灵活的多。
我们项目中也有这个问题,不过我们是通过那个 createFilter来解决的
————————————————————————————————————————
createFilter?可以具体谈谈?
91 楼
rainteen
2007-08-01
Readonly 写道
downpour 写道
我们肯定希望采用一句HQL解决问题,但是此时问题来了,当你试图做SELECT department, count(employee.id) FROM .....这样的HQL时,在Java端,发现没有一个合适的对象可以映射。
从OO的角度,其实可以在Department这个类中加一个employeeSize来表示这种业务场景。但是好像Hibernate无法去做类似的映射。而iBatis在这个方面却灵活的多。
给一个构建函数:
public class Department(Department d, Integer employeeSize)
然后写成这样:
SELECT new Department(department, count(employee.id)) FROM .....
不就OK了吗?
该方法总会报空指针异常: NullPointerException
92 楼
javaIE
2007-08-01
复杂的语言可以简单使用话嘛!尽量使用HQL语句,实在不行还是回归SQL,Hibernate也支持SQL嘛
怕关系复杂在项目 你可以少使用关系映射啊!
总之语言是死的,人却是活的啊
..语言要复杂必然需要抛弃一些东西..我们不能老是盯着它的缺点,能使用它的优点就OK了..
谁没点缺点捏.!?
怕关系复杂在项目 你可以少使用关系映射啊!
总之语言是死的,人却是活的啊
..语言要复杂必然需要抛弃一些东西..我们不能老是盯着它的缺点,能使用它的优点就OK了..
谁没点缺点捏.!?