在之前"Hibernate之查询效率问题"的文章中,谈到了一些数据库对hibernate效率的影响,<o:p></o:p>
就hibernate本身来说,他的效率很高,但常常在项目技术时,地下的效率令人担忧,有个朋友留言提到:<o:p></o:p>
"hibernate 慢一般都是自己设计的问题,本来你用JDBC的时候很简单的一个SQL,你设计放到hibernate 中为了关联,就变成了一个复合SQL,能不慢么?"<o:p></o:p>
确实,由于我们在写代码的时候,在ORM的作用下,越来越少的关心数据库了,也许是面向对象的思想对我们残毒太深,总会把简单的东西复杂化。<o:p></o:p>
下面说一个查询改变的历程:[一下都是系统将hibernate查询或是hql翻译后的sql了]<o:p></o:p>
select employeegr0_.C_OID_EMPLOYEEGRADECHANGE as C1_0_,<o:p></o:p>
salarygrad1_.C_OID_SALARYGRADEDETAIL as C1_1_,<o:p></o:p>
。。。。。。。。。。。。。。。。。。。。。。。。<o:p></o:p>
from TB_CNB_EMPLOYEEGRADECHANGE employeegr0_,<o:p></o:p>
TB_CNB_SALARYGRADEDETAIL salarygrad1_<o:p></o:p>
where employeegr0_.C_CHANGEID = 5308418 and<o:p></o:p>
employeegr0_.C_STRUCTUREDATEID = salarygrad1_.C_STRUCTUREDATEID and<o:p></o:p>
(employeegr0_.C_OLDROW = salarygrad1_.C_ROW and<o:p></o:p>
employeegr0_.C_OLDCOLUMN = salarygrad1_.C_COLUMN or<o:p></o:p>
employeegr0_.C_NEWROW = salarygrad1_.C_ROW and<o:p></o:p>
employeegr0_.C_NEWCOLUMN = salarygrad1_.C_COLUMN)<o:p></o:p>
order by employeegr0_.C_OPERATETIME DESC<o:p></o:p>
<o:p></o:p>
表结构就不介绍了,大概说一下意图吧,就是表TB_CNB_EMPLOYEEGRADECHANGE 可能对应1或2条表TB_CNB_SALARYGRADEDETAIL的记录。<o:p></o:p>
这样的写法,在获得数据后,需要自己写代码合并,比如通过Map的key验证将2个需要合并的对象合并,当然你也可以改写对象的<o:p></o:p>
equals 和 hascode方法,不过这需要根据具体业务,这里适合,2条记录的数据对我都有用,嘿嘿 ! 可惜这种写法在分页显示的要求下被淘汰了。<o:p></o:p>
<o:p></o:p>
改变==========><o:p></o:p>
<o:p></o:p>
select e.c_employeeid,<o:p></o:p>
(select d.c_value<o:p></o:p>
from TB_CNB_SALARYGRADEDETAIL d<o:p></o:p>
where e.C_STRUCTUREDATEID = d.C_STRUCTUREDATEID and<o:p></o:p>
e.C_OLDROW = d.C_ROW and e.C_OLDCOLUMN = d.C_COLUMN) as oldvalue,<o:p></o:p>
(select d.c_value<o:p></o:p>
from TB_CNB_SALARYGRADEDETAIL d<o:p></o:p>
where e.C_STRUCTUREDATEID = d.C_STRUCTUREDATEID and<o:p></o:p>
e.C_newROW = d.C_ROW and e.C_newCOLUMN = d.C_COLUMN) as newvalue <o:p></o:p>
from TB_CNB_EMPLOYEEGRADECHANGE e<o:p></o:p>
where e.C_CHANGEID = 5308418<o:p></o:p>
order by newvalue<o:p></o:p>
这个写法简单,查询出后,不需要自己手动合并,而且可以实现分页显示的功能,不过这时高兴早了些,这样的查询如果用hql写出来执行,<o:p></o:p>
会出错,因为hibernate目前有Bug,不支持这样的写法法。无奈!如果你运行hibernate发现下面异常时,也许就是hibernate不支持你的sql写法。<o:p></o:p>
java.lang.NullPointerException<o:p></o:p>
org.hibernate.hql.antlr.HqlSqlBaseWalker.aliasedSelectExpr(HqlSqlBaseWalker.java:1703)<o:p></o:p>
org.hibernate.hql.antlr.HqlSqlBaseWalker.selectExprList(HqlSqlBaseWalker.java:1474)<o:p></o:p>
org.hibernate.hql.antlr.HqlSqlBaseWalker.selectClause(HqlSqlBaseWalker.java:1041)<o:p></o:p>
org.hibernate.hql.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:380)<o:p></o:p>
org.hibernate.hql.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:201)<o:p></o:p>
org.hibernate.hql.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:151)<o:p></o:p>
org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:189)<o:p></o:p>
org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:130)<o:p></o:p>
org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:83)<o:p></o:p>
org.hibernate.impl.SessionFactoryImpl.getQuery(SessionFactoryImpl.java:427)<o:p></o:p>
org.hibernate.impl.SessionImpl.getQueries(SessionImpl.java:884)<o:p></o:p>
org.hibernate.impl.SessionImpl.list(SessionImpl.java:834)<o:p></o:p>
org.hibernate.impl.QueryImpl.list(QueryImpl.java:74)<o:p></o:p>
改变==========><o:p></o:p>
<o:p></o:p>
select e.c_employeeid,<o:p></o:p>
d1.c_value, d2.c_value<o:p></o:p>
from TB_CNB_EMPLOYEEGRADECHANGE e,<o:p></o:p>
TB_CNB_SALARYGRADEDETAIL d1 ,<o:p></o:p>
TB_CNB_SALARYGRADEDETAIL d2 <o:p></o:p>
where e.C_CHANGEID = 5308418 <o:p></o:p>
and e.C_STRUCTUREDATEID = d1.C_STRUCTUREDATEID and<o:p></o:p>
e.C_OLDROW = d1.C_ROW and e.C_OLDCOLUMN = d1.C_COLUMN<o:p></o:p>
and e.C_STRUCTUREDATEID = d2.C_STRUCTUREDATEID and<o:p></o:p>
e.C_newROW = d2.C_ROW and e.C_newCOLUMN = d2.C_COLUMN<o:p></o:p>
order by d2.c_value<o:p></o:p>
这样写法可以获得和上面相同的结果,不同的是hibernate对这种写法是支持的,也方便的实现分页功能。<o:p></o:p>
总结性的说,为了提高hibernate效率或者是避开一些hibernate的Bug,我们要灵活运行sql的不同写法,而且这也许让我们用更精炼的代码写程序。<o:p></o:p>
<o:p></o:p>
<o:p> </o:p>
分享到:
相关推荐
高级SQL写法
高性能数据仓库引高性能数据仓库引擎Sybase IQ的SQL写法擎Sybase IQ的SQL写法
详细、具体地介绍了关于DB2常用的一些SQl写法,有利于帮助初学者学习DB2的一些基本操作,程序的编写。
博文链接:https://dapeng.iteye.com/blog/146431
sql学习 集合写法.sql
这里罗列了,PB中关于控制数据库写法与SQL不同之处
耗费了本人大量心血的经典Mysql语句写法 颠覆普通程序员思维定式的经典突破 值得一看 不看不知道 看了之后豁然开朗
java JDBC连接不同的数据库写法sql,oracle,mysql 的很好例子
NULL 博文链接:https://beisicao.iteye.com/blog/955674
mysql只取年月日的SQL写法
自己整理的有关SQL的基本语法,该文档里为oracle的查询、修改,合并,递归查询的语句及例子,欢迎下载,评分
五种提高 SQL 性能的方法,开发过程中性能是最重要的,SQL的写法可以影响的性能,因为调用SQL非常频繁,所以提高SQL的性能非常重要
sql学习 执行计划SQL写法差异改变之1_with子句.sql
sql学习 执行计划SQL写法差异改变之3_rownum分页.sql
sql学习 执行计划SQL写法差异改变之2_insert all.sql
sql学习 执行计划SQL写法差异改变之4_rownum实体化.sql
sql学习 执行计划SQL写法差异改变之6_缓存结果影响.sql
sql学习 执行计划SQL写法差异改变之7_分区条件有无.sql
sql学习 执行计划SQL写法差异改变之5_rowid 的影响.sql