锁定老帖子 主题:数据库动态查询最佳实现
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2009-03-24
最后修改:2009-04-09
上次发表过这样的介绍,可能是我介绍的不够准确,太多人都没有搞明白(挺郁闷,当然也请大家将文章能够看的仔细点,主要是提供针对hibernate查询不足的弥补(当然这种做法并不局限于hibernate,事实上是针对所有涉及数据库查询的一个非常好的解决办法,这里且拿hibernate说事),简单的查询可以不考虑如:User user=(User)this.getHibernateTemplate().get(User.class,id); this.getHibernateTemplate().find("from User where enable=?","") ,这些大家其实都差不多,还有就是hibernate的条件查询Criteria很多人都会就不特别说了)。 还是开门见山,本文所要介绍的是针对数据库查询(当然要是ldap什么的基于查询指令的都适用),其目的在于将sql跟代码进行分离,同时能够保持sql或hql语句的 结构完整性(写sql的步骤一般是:在数据库客户端整理好sql并排版好放到代码中用stringbuffer拼起来,要是修改就痛苦了,还得调试代码得到整个语句),请好好看上面红色字的内容,平时是不是这样做的?如果是你就接着看下面的内容,对你帮助很大! 我们有很多时候数据库查询是由多个条件组合而成,但究竟是哪个条件是不确定的 展示一下效果: 提示一下,本功能支持hql查询如(对于hql优点主要体现在查询条件不固定时,hql写法非常优雅): <sql-query name="hr_searchOrganInfo">
本功能最大的优点在于动态查询条件时hql或sql的写法非常的优雅,结构完整! sql语句可以是 select * from t where t.name=:name and t.createDate>:createDate 不一定是?号,以解除使用者需要记住参数顺序 的烦恼。 1、分页调用 通过反调映射到对象 PaginationModel findPageByJdbc(final String sqlOrNamedSql,
直接返回数据库结果结合,不映射对象 PaginationModel findPageByJdbc(final String sqlOrNamedSql,
直接转VO式调用 PaginationModel findPageByJdbc(final String sqlOrNamedSql, 2、非分页反调方式 直接数据库数据集合返回 List findByJdbcQuery(final String sqlOrNamedSql, 通过反调映射到对象 List findByJdbcQuery(final String sqlOrNamedSql, 直接转VO对象调用 List findByJdbcQuery(final String sqlOrNamedSql, hql的调用差不多:findByhql 或findPageByhql,参数当然就没有voClass和RowCallbackHandler了,因为hql返回的就是对象集合!
工作机理很简单,就是通过判断参数是否为null(结合sql特性如is null)对sql语句进行重新整理,后台提供了convertSqlParams功能将特定值转为null this.findPageByJdbc("hr_getOrganInfoByNo", null,new Object[] { organNO,this.convertSqlParams(status,"-1")}, pageModel,OrganInfoVO.class); 提供java反射器直接映射成VO,也提供了RowCallbackHandler通过反调方式生成VO,当然voClass和RowCallbackHandler都为null,就直接返回数组集合!
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-03-24
我以前也觉得sql很丑陋,但是后来发现它后面还有一套优雅的代数学,反而就觉得sql外面的那些东西很丑陋了……
|
|
返回顶楼 | |
发表时间:2009-03-24
最后修改:2009-04-09
night_stalker 写道 我以前也觉得sql很丑陋,但是后来发现它后面还有一套优雅的代数学,反而就觉得sql外面的那些东西很丑陋了……
不想多评价,程序的优雅性和可读性以及提供给开发人员的简单性都很重要,我们的团队现在都在这么用,代码量大大减少,sql语句维护也简单方便,要修改直接从xml文件中抠出来改改再放进去,从他们的感受来说已经极其依赖这样的东西了,因为实在是简单易用和直观! 而且在xml中sql的结构仍然是非常清晰,这对后期维护是非常重要的! |
|
返回顶楼 | |
发表时间:2009-03-27
现在人真怪异了,难道大家做开发数据库不是用的最多嘛?做系统不就是为了查询统计嘛?查询难道就不涉及到sql或hql嘛?写sql和hql难道你们就习惯用
if(查询条件不为空或什么) queryStr.append()吗? 我真服了,如此常用的好东西没有人关心,数据库部分在开发中占多大比重不清楚?! 就整天胡扯一些飘忽的技术,有人说面向对象根本不需要写sql,hql多表时性能是低劣的,有些功能hql是没有办法做到的,所以简单的可以用hql,复杂的需要用sql,当然不管是sql还是hql动态参数时if() append()是极其丑陋的,sql或hql写在代码中也是极其痛苦的! |
|
返回顶楼 | |
发表时间:2009-03-27
最后修改:2009-03-27
哈哈,我在站内查了一下,关于动态查询的,如介绍DynamicQueryTool什么的(被评为精华贴),说实话我的这种做法非常优雅,一点都不夸张!
|
|
返回顶楼 | |
发表时间:2009-03-27
MakeLove 写道 黄婆的厉害 哈哈,实事求是而已!再就是想把这种思想推荐给大家的心情比较急切,希望大家能够用上正真好的东西和好的方法,更希望大家能够真正的看文章,更要看三种写法的特点,有益就发言,有更好的想法可以提出来! |
|
返回顶楼 | |
发表时间:2009-03-27
请问动态表名如何实现?
|
|
返回顶楼 | |
发表时间:2009-03-27
longrui 写道 请问动态表名如何实现? 这要看你怎么动态表法了,#[]支持嵌套如#[#[]]其实就相当于if( if()),通过这个其实是可以做到动态表的,但是不建议这么做,为什么不把这种问题作为服务逻辑呢?多写几个sql,在service中判断不同类型选择调用不同sql不就行了,动态也得把握一个度,我的目标是保持sql的结构,将sql从代码中脱离,所以我建议你写多个sql,或则针对这类极其特殊的问题用特殊办法对待(我们要为解决98%的问题,2%的特殊情况完全可以自行处理,解决了98%何必又那么苛刻要100%呢,98%还不比0%好嘛?) |
|
返回顶楼 | |
发表时间:2009-03-27
大家在这篇2年前的帖子中讨论过各种类似做法:
http://www.iteye.com/topic/58834 你提出的想法是在约定大于配置上更进一步,少去了一些tag,如果更进一步,连#[]都可以省略,可以and开头,换行结尾作为匹配: from HrOrganInfo where 1=1 and createDate>= ? and createDate<= ? and ORGAN_NO like ? and ORGAN_NAME like ? and IS_ACTIVE = ? |
|
返回顶楼 | |
发表时间:2009-03-27
最后修改:2009-03-27
QuakeWang 写道 大家在这篇2年前的帖子中讨论过各种类似做法:
http://www.iteye.com/topic/58834 你提出的想法是在约定大于配置上更进一步,少去了一些tag,如果更进一步,连#[]都可以省略,可以and开头,换行结尾作为匹配: from HrOrganInfo where 1=1 and createDate>= ? and createDate<= ? and ORGAN_NO like ? and ORGAN_NAME like ? and IS_ACTIVE = ? 不好意思,写这个东西前没有看过其它的写法,只是阿里的朋友给我展示ibatis时让我产生了灵感,我们已经用了好几个月了,大家用的非常舒服,sql在客户端写完粘进xml稍微改动一下就可以,要是修改拿出来改改就行,and这种是不现实的,嵌套什么的就非常麻烦,如何做到#[#[]]而且and 是sql中的字符这样做是不行的,一定需要找非常特殊的符号来约定。 |
|
返回顶楼 | |