查看: 7207|回复: 11

[原创] 数据库动态查询最佳实现 陈氏查询

[复制链接]
论坛徽章:
0
跳转到指定楼层
1#
发表于 2009-4-26 18:19 | 显示全部楼层 回帖奖励 |倒序浏览 |阅读模式
我占个位,命名为陈氏查询!一帮所谓牛人总说不是什么创新,为我的“陈氏查询”名称感到很不爽!但他们所提供的证据范例个人认为连ibatis的做法都不如,反增加了开发的麻烦!
还是开门见山,本文所要介绍的是针对数据库查询(当然要是ldap什么的基于查询指令的都适用),其目的在于将sql跟代码进行分离,同时能够保持sql或hql语句的
结构完整性(写sql的步骤一般是:在数据库客户端整理好sql并排版好放到代码中用stringbuffer拼起来,要是修改就痛苦了,还得调试代码得到整个语句),请好好看上面红色字的内容,平时是不是这样做的?如果是你就接着看下面的内容,对你帮助很大!
我们有很多时候数据库查询是由多个条件组合而成,但究竟是哪个条件是不确定的
展示一下效果:
提示一下,本功能支持hql查询如(对于hql优点主要体现在查询条件不固定时,hql写法非常优雅):
<sql-query name="hr_searchOrganInfo">
  <![CDATA[
  from HrOrganInfo
  where 1=1
  #[and createDate>=? and createDate<=?]
  #[and ORGAN_NO like ?]
  #[and ORGAN_NAME like ?]
  #[and IS_ACTIVE=?]
]]>
</sql-query>



本功能最大的优点在于动态查询条件时hql或sql的写法非常的优雅,结构完整!
同时#[]支持嵌套,如:
#[]相当于if判断
select  t.*
from table_name t
where 1 = 1   
           and t.type=:type
          #[and t.status=:status   
             and t.orderId=(select orderId   
                                     from t2
                                     #[where t2.name  like :name]
                                      )
             ]  

调用方法:
   sql语句可以是
   select * from t where t.name=:name and t.createDate>:createDate 不一定是?号,以解除使用者需要记住参数顺序
的烦恼。
1、分页调用
    通过反调映射到对象
    PaginationModel findPageByJdbc(final String sqlOrNamedSql,
   final String[] paramsNamed, final Object[] paramsObj,
   final PaginationModel paginationModel,
   final RowCallbackHandler rowCallbackHandler);



   直接返回数据库结果结合,不映射对象
   PaginationModel findPageByJdbc(final String sqlOrNamedSql,
   final String[] paramsNamed, final Object[] paramsObj,
   final PaginationModel paginationModel);



   直接转VO式调用
    PaginationModel findPageByJdbc(final String sqlOrNamedSql,
   final String[] paramsNamed, final Object[] paramsObj,
   final PaginationModel paginationModel, final Class voClass);

2、非分页反调方式
   直接数据库数据集合返回
   List findByJdbcQuery(final String sqlOrNamedSql,
   final String[] paramsNamed, final Object[] paramsValue);

通过反调映射到对象
   List findByJdbcQuery(final String sqlOrNamedSql,
   final String[] paramsNamed, final Object[] paramsValue,
   final RowCallbackHandler rowCallHandler)

  直接转VO对象调用
   List findByJdbcQuery(final String sqlOrNamedSql,
   final String[] paramsNamed, final Object[] paramsValue,
   final Class voClass)

hql的调用差不多:findByhql 或findPageByhql,参数当然就没有voClass和RowCallbackHandler了,因为hql返回的就是对象集合!


工作机理很简单,就是通过判断参数是否为null(结合sql特性如is null)对sql语句进行重新整理,后台提供了convertSqlParams功能将特定值转为null
this.findPageByJdbc("hr_getOrganInfoByNo", null,new Object[] { organNO,SqlUtil.filterEquals(status,"-1")}, pageModel,OrganInfoVO.class);
提供java反射器直接映射成VO,也提供了RowCallbackHandler通过反调方式生成VO,当然voClass和RowCallbackHandler都为null,就直接返回数组集合!

目前增加了缓存机制
一句分页查询就这么简单:
return this.findPageByJdbc("security_findRole", null, new Object[] {
    SqlUtil.filterEqual(roleVO.getActiveFlag(), SystemConstants.FULL),
    SqlUtil.filterEqual(roleVO.getLayerFlag(),  SystemConstants.FULL),
    SqlUtil.filterBlank(roleVO.getAllRoleNos()) }, pageModel, RoleVO.class);

如果你想藐视请你拿出你的写法,要是更简单我服你,要是觉得不错请回帖顶一下(实在是看到太多没有看明白就否定一切的人)


[ 本帖最后由 zhongxuchen 于 2009-6-23 17:34 编辑 ]
论坛徽章:
0
2#
 楼主| 发表于 2009-5-2 14:51 | 显示全部楼层
你看清楚了文章没有呀?没有说全部跟ibatis比,但查询时比ibatis好的,你怎么打击我也没有用呀,ibatis的动态查询就是没有我这个优雅呀,ibatis我也用过呀!sql结构打乱了,我这个也是支持参数命名的,请看清楚再回复(顺便再提醒一下,不仅仅是sql、hql等等的都一样支持)
select  t.*
from table_name t
where 1 = 1   
           and t.type=:type
          #[and t.status=:status   
             and t.orderId=(select orderId   
                                     from t2
                                     #[where t2.name  like :name]
                                      )
             ]

使用道具 举报

回复
论坛徽章:
0
3#
 楼主| 发表于 2009-5-5 00:27 | 显示全部楼层

回复 #9 piliskys 的帖子

哈哈,不是打击不打击的事情,我认为你根本就没有看明白我说的是什么,我强调的是sql的写法,动态参数,我提供的是对sql语句的动态处理
查询条件不定,最终执行的sql是不一样的,你说的跟我说的不是一码事,我强调的是动态以及sql和代码的分离,你确信明白了再提打击!不要没有看明白什么意思,上来就搞什么打击,这样是不对的!
请看这句:老兄你说的支持数组,请看文章调用方法那块,其实调用时及其简单的就是一句话!你说的对返回数据的封装,我告诉你我提供了3种方式:
在调用时提供了多态方式参数有voClass、rowCallBackHandler(反调自己实现接口,spring jdbcTemplate中有类似实现,请参看),如果这两个参数都为null就返回数组集合,我想这应该完全满足要求了吧?要快速对象封装就用voClass,比较复杂的封装就自己实现RowCallBackHandler接口,如果不需要封装就什么也不传,直接返回ResultSet放到List中的结果,哈哈这里不多阐述了,我非常希望大家能够认真阅读后再提出自己的见解,不要仅看一眼就随意评价,好坏自有分说,我乐意听到不同的声音,但没有看明白意思就评说我认为缺乏严谨的做事态度,对我的文章也不够尊重!
select t.*
          ,t1.NAME
from OA_CAR_REGIST t,HR_STAFF_INFO t1
where 1=1
         and t1.STAFF_NO=t.CHAUFFEUR
         and t.IS_ACTIVE=?
         #[and t.CAR_MODE like ? ] <!--?对应的值为null 这一块就没有了,这不是spring里面所提供的吧--->
         #[and t1.NAME like ? ]
         #[and t.REGIST_DATE>=? and t.REGIST_DATE<= ? ]
         #[and t.DISABLE_DATE>=? and t.DISABLE_DATE<= ? ]
         #[and t.ASSET_TYPE= ? ]
这样的sql判断参数值,#[]中的内容有可能会被切除,也许最终的sql是:
select t.*
          ,t1.NAME
from OA_CAR_REGIST t,HR_STAFF_INFO t1
where 1=1
         and t1.STAFF_NO=t.CHAUFFEUR
         and t.IS_ACTIVE=?

select t.*
          ,t1.NAME
from OA_CAR_REGIST t,HR_STAFF_INFO t1
where 1=1
         and t1.STAFF_NO=t.CHAUFFEUR
         and t.IS_ACTIVE=?
         and t.ASSET_TYPE= ?


要是老兄果然是没有看明白,那我真为自己叫屈,我真是服了,太多人都是对待事情是不踏实严谨,你还算不错了,javaeye上的有一个上来就声称写sql就是过时(当然我的这个也是支持hql等等的,这小子根本就没有明白我所阐述的一个机理),还有就是把别人想的特土,hibernate的条件查询还有this.getHibernateTemplate.get(Id)之类的别人也不知道一样,我当时还特别在文章头上说了,简单的做法不多强调,因为简单的大家做法都差不多,写在代码中也无所谓!更有甚者以用了hibernate annotation就标榜自己先进!我真服了!

[ 本帖最后由 zhongxuchen 于 2009-5-5 00:59 编辑 ]

使用道具 举报

回复
论坛徽章:
0
4#
 楼主| 发表于 2009-5-5 00:28 | 显示全部楼层

回复 #9 piliskys 的帖子

哈哈,不是打击不打击的事情,我认为你根本就没有看明白我说的是什么,我强调的是sql的写法,动态参数,我提供的是对sql语句的动态处理,
查询条件不定,最终执行的sql是不一样的,你说的跟我说的不是一码事,我强调的是动态以及sql和代码的分离,你确信明白了再提打击!不要没有看明白什么意思,上来就搞什么打击,这样是不对的!
select t.*
          ,t1.NAME
from OA_CAR_REGIST t,HR_STAFF_INFO t1
where 1=1
         and t1.STAFF_NO=t.CHAUFFEUR
         and t.IS_ACTIVE=?
         #[and t.CAR_MODE like ? ] <!--?对应的值为null 这一块就没有了,这不是spring里面所提供的吧--->
         #[and t1.NAME like ? ]
         #[and t.REGIST_DATE>=? and t.REGIST_DATE<= ? ]
         #[and t.DISABLE_DATE>=? and t.DISABLE_DATE<= ? ]
         #[and t.ASSET_TYPE= ? ]
这样的sql判断参数值,#[]中的内容有可能会被切除,

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表