精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-09-14
庄表伟 写道 记得以前robbin还说过,Hibernate生成的SQL,非常的优化,效率极高,非JDBC顶级高手,勿须尝试写出比Hibernate更加好的SQL。
怎么现在就成了:“现在极其厌恶Hibernate生成的SQL,又臭又长,极难阅读。”? 正所谓“此一时,彼一时”嘛, ,说来说去,还是个场景问题,性能 vs 移植性... |
|
返回顶楼 | |
发表时间:2006-09-15
Readonly 写道 偶严重反对robbin对于HSQL的看法,如果没有HSQL的话,让偶回到过去那种写一个产品,要在N种数据库上调试不同的SQL兼容性,简直是噩梦啊。
COC就更没有啥话好说了,你完全可以给Hibernate加个COC plugin,只支持native PK,只支持1:N,只支持字段和数据库栏位同名。批评Hibernate不够自动化,就象批评手自一体的BMW比自动挡的KIA难用一样好笑... Hibernate生成的SQL倒是没有啥感觉,因为基本上hibernate.show_sql都是false,只有很特殊的调试情况下,才需要打开这个参数去看生成的sql是怎么样的吧? 用jrc sql,价格便宜量又足。 |
|
返回顶楼 | |
发表时间:2006-09-15
庄表伟 写道 记得以前robbin还说过,Hibernate生成的SQL,非常的优化,效率极高,非JDBC顶级高手,勿须尝试写出比Hibernate更加好的SQL。
怎么现在就成了:“现在极其厌恶Hibernate生成的SQL,又臭又长,极难阅读。”? Hibernate生成的SQL确实不错,这方面我承认,但Hibernate把表名,字段名都自作主张加上了别名,看起来太难看了,阅读起来非常不友好。 |
|
返回顶楼 | |
发表时间:2006-09-15
hibernate.format_sql = true
如果想要仔细看Hibernate生成的SQL语句,将format_sql设为true可以很大程度地减轻痛苦…… 再加上这个的话: hibernate.use_sql_comments = true 个人认为 [可读性 + 可定位性] 会更好。 当然,这两个一起来的话也会造成SQL在console中显示的篇幅很大。例如: /** * 以下是Hibernate在控制台中自动生成的log */ Hibernate: /* criteria query */ select this_.id as id88_0_, this_.flag as flag88_0_, this_.description as descript3_88_0_, this_.mobilizationDate as mobiliza4_88_0_, this_.recordId as recordId88_0_, this_.deptFromId as deptFromId88_0_, this_.deptToId as deptToId88_0_ from Mobilization this_ where this_.flag=? order by this_.id asc Hibernate: /* load net.example.model.PersonnelRecord */ select personnelr0_.id as id91_0_, personnelr0_.flag as flag91_0_, personnelr0_.birthDate as birthDate91_0_, personnelr0_.deptId as deptId91_0_, personnelr0_.eduQualificationId as eduQuali5_91_0_, personnelr0_.firstWorkDate as firstWor6_91_0_, personnelr0_.gender as gender91_0_, personnelr0_.idNumber as idNumber91_0_, personnelr0_.nationalityId as national9_91_0_, personnelr0_.originDate as originDate91_0_, personnelr0_.politicalConditionId as politic11_91_0_, personnelr0_.socialRelation as socialR12_91_0_, personnelr0_.description as descrip13_91_0_, personnelr0_.jobPositionId as jobPosi14_91_0_, personnelr0_.jobTitleId as jobTitleId91_0_, personnelr0_.jobTypeId as jobTypeId91_0_, personnelr0_.personName as personName91_0_, personnelr0_.iconUrl as iconUrl91_0_, personnelr0_.officialFlagId as officia19_91_0_, personnelr0_.marriageFlagId as marriag20_91_0_, personnelr0_.personnelNumber as personn21_91_0_, personnelr0_.quitWorkDate as quitWor22_91_0_, personnelr0_.address as address91_0_, personnelr0_.cellPhoneNumber as cellPho24_91_0_, personnelr0_.email as email91_0_, personnelr0_.phoneNumber as phoneNu26_91_0_, personnelr0_.nativeLocation as nativeL27_91_0_ from PersonnelRecord personnelr0_ where personnelr0_.id=? Hibernate: /* load net.example.model.Department */ select department0_.id as id81_0_, department0_.flag as flag81_0_, department0_.deptName as deptName81_0_, department0_.deptTypeId as deptTypeId81_0_, department0_.description as descript5_81_0_, department0_.deptNumber as deptNumber81_0_ from Department department0_ where department0_.id=? Hibernate: /* load net.example.model.Department */ select department0_.id as id81_0_, department0_.flag as flag81_0_, department0_.deptName as deptName81_0_, department0_.deptTypeId as deptTypeId81_0_, department0_.description as descript5_81_0_, department0_.deptNumber as deptNumber81_0_ from Department department0_ where department0_.id=? |
|
返回顶楼 | |
发表时间:2006-09-15
liuwangxia 写道 robbin 写道 2、现在极其厌恶Hibernate生成的SQL,又臭又长,极难阅读。 深有同感!
原因是要为表生成别名,还要为字段生成别名,而且当 SQL 只涉及到一张表的时候还要为表生成一个别名 this_,为每个字段生成别名 *_0_,浪费! 对了,那位热心人能将这个问题提交给 Hibernate 开发组试试看! 机器自动生成,而且还得考虑不能触犯到保留字(java sql 数据库自身),这样多的要求,还得易看!其实hibernate做得很好了,只是我们不知道他们所考虑的。 |
|
返回顶楼 | |
发表时间:2006-09-15
ylt 写道 我同意Readonly的观点。如果不用hql,想实现数据库兼容就太难了。 举个例子,在很多手工录入的表格中都要记录录入时间/操作人/备注,我在java中使用date/person/comment来表示,可是java的关键字和sql的是不一样的,不同数据库也有各自的扩展关键字,上面那几个字段很可能就是某种数据库的关键字。用hql,我所有的查询语句就可以保持统一,切换数据库只需要修改mapping。实际上我写了一个自动根据数据库关键字修改mapping的类,这样连mapping文件也只需要一个。 实现数据库兼容并不象你想象的那么难。:) 我做的平台软件在多种数据库上测试过,包括:Oracle9(10),SqlServer2000,MySql4(5),PostgreSQL8, HyperSonic。 操作包括CRUD,查询也有比较复杂的。 兼容数据库的步骤如下: 1)数据库DDL是要自行处理的。当然可以借助PowerDesigner的自动转换数据库功能,虽然也有bug,其实主要无非就是一些数据类型的转换,手写也可。 2)CRUD之字段类型。JDBC的PreparedStatement已经帮你将所有的字段类型都封装了,不需要为了插入日期型等数据调用数据库本地的函数,ps.setDate()即可。 3)CRUD之SQL语法。ANSI SQL标准虽然贯彻得不够彻底,但常用的语法的确得到了一致认可。比如,表的左外连接在Oracle8里只有a.field1=b.feild2(+)这种方式,但在Oracle9以后,都支持标准的left outer join on语法了。这种语法在上述5种数据库都得到支持。其他的别名的语法也支持良好。 我碰到的一个比较搞的问题就是SQLserver2000种删除语句不能给表设置别名,即不能delete from TABLE a where a.id=?,去除别名无问题。 4)结果分页。这个的确是我碰到的最需额外处理等问题。我就是参考了hibernate的方法解决的。 5)ID生成问题。不同数据库有各自优化的方式,也可以使用通用的方式。也参考hibernate。 6)其他问题。比如Oracle里的hierachical query(connect by语句)在其他的数据库可能没有对等的实现方式,此时无法对此特性跨平台了。 |
|
返回顶楼 | |
发表时间:2006-09-15
AreYouOK? 写道 我现在觉得还是jdbc来的最直接,有什么问题无非就是调试一下sql语句。虽然有时候象是在干体力活,但是多花一分钟的时间写sql语句总比花一个小时去研究hibernate产生的奇奇怪怪的现象要划算。
我把potian举过的例子修改下,假设你对性能感兴趣: 那么通常下hibernate会批量更新,但是A情况下就不会,A情况下如果满足B条件,它又能批量更新,不过你不能用C功能,否则它又不行,你是不是很崩溃?最后你可能要花好几个小时终于弄清楚了这个小问题,那边用jdbc做事的早就做完了。 jdbc大家都会,所以相对于整个团队而言,jdbc程序的可读性很好。而hibernate这种东西太复杂,每个人的掌握程度都不一样。这样,当我阅读或者修改别人的hibernate代码的时候,如果他用到了我不熟悉的功能,那么我总是要先花时间了解一下这个功能,否则当我操作对象的时候,不知道hibernate在后面做了些什么奇奇怪怪的事情,心里太没底。或许你是高手,可是当团队里别人要修改你的程序的时候,他怎么办呢? 用最简单的方式解决问题,是很有道理的。 这个问题有意思。我有同感。 没出现ORM之前就会有人觉得直接写SQL丑陋;现在又会有人觉得用ORM麻烦。 这真是事务发展的规律啊。 JAVA不也面临类似的疑问么? 得到一些也要失去一些。什么也替代不了你自己独立的、因地制宜的、具体问题具体分析的判断。 |
|
返回顶楼 | |
发表时间:2006-09-15
Allen的方法时新版本的吧,
那个版本开始的? |
|
返回顶楼 | |
发表时间:2006-09-15
ylt 写道 Readonly 写道 我同意Readonly的观点。如果不用hql,想实现数据库兼容就太难了。 举个例子,在很多手工录入的表格中都要记录录入时间/操作人/备注,我在java中使用date/person/comment来表示,可是java的关键字和sql的是不一样的,不同数据库也有各自的扩展关键字,上面那几个字段很可能就是某种数据库的关键字。用hql,我所有的查询语句就可以保持统一,切换数据库只需要修改mapping。实际上我写了一个自动根据数据库关键字修改mapping的类,这样连mapping文件也只需要一个。 实现数据库兼容并不象你想象的那么难。:) 我做的平台软件在多种数据库上测试过,包括:Oracle9(10),SqlServer2000,MySql4(5),PostgreSQL8, HyperSonic。 操作包括CRUD,查询也有比较复杂的。 兼容数据库的步骤如下: 1)数据库DDL是要自行处理的。当然可以借助PowerDesigner的自动转换数据库功能,虽然也有bug,其实主要无非就是一些数据类型的转换,手写也可。 2)CRUD之字段类型。JDBC的PreparedStatement已经帮你将所有的字段类型都封装了,不需要为了插入日期型等数据调用数据库本地的函数,ps.setDate()即可。 3)CRUD之SQL语法。ANSI SQL标准虽然贯彻得不够彻底,但常用的语法的确得到了一致认可。比如,表的左外连接在Oracle8里只有a.field1=b.feild2(+)这种方式,但在Oracle9以后,都支持标准的left outer join on语法了。这种语法在上述5种数据库都得到支持。其他的别名的语法也支持良好。 我碰到的一个比较搞的问题就是SQLserver2000种删除语句不能给表设置别名,即不能delete from TABLE a where a.id=?,去除别名无问题。 4)结果分页。这个的确是我碰到的最需额外处理等问题。我就是参考了hibernate的方法解决的。 5)ID生成问题。不同数据库有各自优化的方式,也可以使用通用的方式。也参考hibernate。 6)其他问题。比如Oracle里的hierachical query(connect by语句)在其他的数据库可能没有对等的实现方式,此时无法对此特性跨平台了。 sql 2000删除时可以设置别名的delete a from table a where a.id = ? 安全起见的话还是需要加一个SQL处理的,毕竟函数 CASE这些也算基本查询了 但不同还是很大的 CRUD问题不大 |
|
返回顶楼 | |
发表时间:2006-09-16
最不爽的是这个。
http://www.iteye.com/topic/244 没想到hibernate性能这个差。 莫非hibernate3.1用了ejb?为什么速度这么慢? 如果这么慢的话,那对于压力比较大的业务,hibernate其实是不能用的。 |
|
返回顶楼 | |