`
zhongxuchen
  • 浏览: 33445 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

开创性的陈氏数据库动态查询设计

阅读更多

(新版增加了直接结果映射VO的功能无需再写rowcallbackhandler了,集成ehcache、memcached提高处理效率)

犹豫了很久,还是决定将自己的东西(sagacity睿智开发框架)的一部分逐步奉献给大家,首先申明一下版权问题,请注明“陈氏查询”!

     进入正题:

     首先介绍一下sagacity(睿智)框架:其包括快速原型的页面框架(这里面也有一个非常独到人性化的界面的设计),sagacity-core核心代码库提供针对企业应用开发所需要的工具类和组件,sagacity-toolkit 工具库,包括快速原型项目生成,excel导入工具(用于项目试运行阶段数据初始化);sagacity-struts:基于struts2+spring+hibernate+sitemesh+spring security技术以实际企业开发项目为背景非常实用演示项目。sagacity项目从实际项目出发,贯穿整个项目周期提供优雅的实现以及从开发人员的角度着眼简化开发难度!这里不一一而谈。

     第一讲:陈氏查询

     先抛一个问题:大家平时做数据库查询时查询条件很多也不定时怎么写hql以及sql语句?

     比如:

     queryStr.append("select *  ");
     queryStr.append("from OA_CAR_REGIST t ");
     queryStr.append("where 1=1 ");

     if(CarRegiestVO.isActive!=null)
          queryStr.append(" and t.IS_ACTIVE is ? ");

     if(CarRegiestVO.beginDate!=null && CarRegiestVO.endDate!=null)
          queryStr.append("   and t.REGIST_DATE>=? and t.REGIST_DATE<= ? ");

     if(CarRegiestVO.carMode!=null)
          queryStr.append("      and t.CAR_MODE like  "+carMode+"%");
     sql结构非常混乱,从数据库客户端写好的sql语句还得用stringBuffer给拼接起来,以后要是改写一下语句还得debug程序得到最后的语句,太累了!

     我们的做法:

     我们的项目基于hibernate的,如下基于hibernate NamedQuery扩展。

     <hibernate-mapping>
 <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>
 
 <sql-query name="hr_loadOrganTree">
 <![CDATA[
  select  b.ORGAN_NO,b.ORGAN_NAME,b.PRE_ORGAN_NO,0 AS TYPE
  from HR_ORGAN_INFO b
  where 1=1
  #[and b.ORGAN_NO=?]
  #[and b.IS_ACTIVE=?]
  union
  select b.ORGAN_NO,b.ORGAN_NAME,b.PRE_ORGAN_NO,0 AS TYPE
  from HR_ORGAN_INFO a,HR_ORGAN_INFO b
  where 1=1
  #[and a.ORGAN_NO=b.PRE_ORGAN_NO and (a.ORGAN_NO=? or b.PRE_ORGAN_NO=a.ORGAN_NO)]
  #[and b.IS_ACTIVE=?]
 ]]>
 </sql-query>
  对于不定的查询条件以#[和]标记对,支持嵌套

我们的调用过程:

 /**
  * 分页方式查询机构信息
  * @param organInfoVO
  * @param pageModel
  * @return
  * @throws Exception
  */
 public PaginationModel searchOrganInfo(OrganInfoVO organInfoVO,
   PaginationModel pageModel) throws Exception {
  return this.findPageByhql("hr_searchOrganInfo", null, new Object[] {
    organInfoVO.getBeginDate(),
    organInfoVO.getEndDate(),
    organInfoVO.getOrganNo(),
    organInfoVO.getOrganName(),
    organInfoVO.getIsActive() },
    pageModel);
 }

    

在我们BaseDAOSupport中提供findPageByHql以及其它大量针对数据库查询的方法,在方法调用时只需要将参数完整化的以对象数组(或List),对于如状态选择:-1表示全部等特性,以及blank值的处理,我们提供了convertSqlParams(objects),convertSqlParams(obj,new Object[-1,""]),判断对象为空或-1则转为

null,用法:

 return this.findPageByhql("hr_searchOrganInfo", null, new Object[] {
    organInfoVO.getBeginDate(),
    organInfoVO.getEndDate(),
    organInfoVO.getOrganNo(),
    organInfoVO.getOrganName(),
    convertSqlParams(organInfoVO.getIsActive() ,-1)},
    pageModel);
 }

当然也可以批量转(转""为null)

return this.findPageByhql("hr_searchOrganInfo", null, convertSqlParams(new Object[] {
    organInfoVO.getBeginDate(),
    organInfoVO.getEndDate(),
    organInfoVO.getOrganNo(),
    organInfoVO.getOrganName(),
    organInfoVO.getIsActive() }),
    pageModel);
 }

 

实现原理很简单(个人觉得这只是一个idea不属于技术范畴,说穿了谁都能实现只是实现的代码简繁而已),判断#[]中的问号所对应的参数是否为null(当然考虑like 和is,like将值直接替换进去,is 判断数据类型是否为null以及boolea类型,不是则将#[]内容切除),为null将#[]内容切除,是则将#[和]标记用""替换掉,这样整体

代码实现起来优雅简单,sql语句的可读性和可维护性大大增强!

当然你会找出一个极其变态难处理的sql整合(目前我们项目中还没有遇到),我们这个东西怎么做呢?其实

findPageByhql("hr_searchOrganInfo",param..param),第一个参数既可是是NamedQuery也可以是sql(hql)语句,自己组合咯,特殊问题特殊对待。

sagacity的宗旨在于不强迫你改变你的习惯,考虑特殊情况,为开发提供方便!

sagacity代码这几天整理一下,重新划分一下,将标签部分独立出来,减少耦合性将尽快对大家提供后台开发所需要的代码!

期待第二讲吧!

谢谢支持!

另外对于参数位置不容易记问题,其实我们这边是提供了

/**
  * @todo 分页查询
  * @param hql
  * @param paramNames
  *            :参数名称
  * @param params
  *            :参数值
  * @param paginationModel
  *            :分页模型,含页号
  * @return
  */
 protected PaginationModel findPageByhql(final String hqlOrNamedQuery,
   final String[] paramNamed, final Object[] paramsValue,
   final PaginationModel paginationModel) {

}

paramNamed 参数方式的。

哈哈,说一下ibatis,ibatis确实能够实现类似的功能,但个人觉得没有这个灵活和优雅,下面发一张图,ibatis多条件动态查询无法让sql看起来如此优雅整洁:



 

再对比一下ibatis的做法:

<statement id="someName" resultMap="account-result" >
select * from ACCOUNT
<dynamic prepend="where">
<isGreaterThan prepend="and" property="id" compareValue="0">
ACC_ID = #id#
</isGreaterThan>
<isNotNull prepend=”and" property="lastName">
ACC_LAST_NAME = #lastName#
</isNotNull>
</dynamic>
order by ACC_LAST_NAME
</statement>

 

效果一目了然了,代码多,还破坏了sql的整体性

    

  • 大小: 12.2 KB
分享到:
评论
14 楼 kimmking 2009-02-19  
zhongxuchen 写道
kimmking 写道
有一个简单问题复复杂化的例子:

hibernate的一般用法:

EO eo = new EO();
set get......

query....


这个问题怎么会用这种方式解决呢?直接(EO)this.get(EO.class,id),没有仔细看文章才会有这样的结论,
敢拿出来露当然有一些独到的地方,简单东西其实大家做法都差不多,属于没有必要谈的事情!



lz的文字真费解,你这个替换,其实就是多了一个null判断,难道不属于简单东西
13 楼 kimmking 2009-02-19  
huhuanqadn 写道
嗯,不错,很有面向对象的风格。



晕,还真没看出来
12 楼 E生迅徒 2009-02-19  
名字有待优化嘛
11 楼 chenlb 2009-02-19  
"陈氏", 一套功夫? ...

命名太没水平
10 楼 clasp 2009-02-19  
我比侧向与用ibatis
9 楼 xuyao 2009-02-19  
还行,思路挺好,不过啥叫“陈氏查询”
8 楼 zhongxuchen 2009-02-18  
kimmking 写道
有一个简单问题复复杂化的例子:

hibernate的一般用法:

EO eo = new EO();
set get......

query....


这个问题怎么会用这种方式解决呢?直接(EO)this.get(EO.class,id),没有仔细看文章才会有这样的结论,
敢拿出来露当然有一些独到的地方,简单东西其实大家做法都差不多,属于没有必要谈的事情!
7 楼 huhuanqadn 2009-02-17  
嗯,不错,很有面向对象的风格。
6 楼 zhongxuchen 2009-02-17  
其实这个东西并不局限于hibernate,我们项目中是提供了针对hibernate的集成,目的是提供针对多条件查询
5 楼 zhongxuchen 2009-02-17  
没错,灵感来自ibatis
4 楼 zhongxuchen 2009-02-17  
哈哈,简单的hibernate query查询当然不需要这么搞了,我们针对复杂多条件查询,简单的可以采用Criteria,我这里只强调这个方式,具体jdbc查询的反调对象这类的不着重说,
BaseDAOSupport中提供了实现:
protected List findByJdbcQuery(String sqlOrNamedSql,Object paramsObj,RowCallbackHandler rowCallHandler)
3 楼 yingzhouxue 2009-02-17  
很好,实现类似于ibatis
2 楼 kimmking 2009-02-17  
有一个简单问题复复杂化的例子:

hibernate的一般用法:

EO eo = new EO();
set get......

query....
1 楼 cftang9999 2009-02-17  
支持一下

相关推荐

    剑桥大学 多学科设计项目数据库(英文)

    数据库的创建得到了Cambridge-MIT Institute (CMI)的支持,这是一个剑桥大学与麻省理工学院之间的开创性合作机构,自2000年成立以来,CMI致力于通过提高大学与产业间知识交流的有效性,教育培训领导人才,以及为大学...

    数据库原理

    老一代专家如萨师煊教授等作出了开创性贡献,80年代数据库技术开始普及,90年代国产数据库技术开始发展,2007年国产数据库市场份额首次被权威机构报告提及。 3. 数据库的种类:数据库根据其数据模型和应用领域不同...

    斯坦福STREAM数据库

    总而言之,斯坦福STREAM数据库是一个开创性的尝试,它在流数据管理领域提出了创新的解决方案,为后来的数据库技术发展奠定了基础。尽管项目本身已结束,但其理念和技术仍然影响着当今的数据处理领域,特别是对于需要...

    数据库原理第1章 绪论.ppt

    1. **数据库系统概述**:介绍数据库系统的基本概念,包括数据库的起源和发展历程,例如Honeywell公司的IDS系统对数据库技术的开创性贡献,以及关系数据库如何逐渐成为主流。 2. **数据模型**:探讨不同类型的数据...

    数据库系统实现(斯坦福大学教材)

    Ullman和Jennifer Widom是斯坦福大学著名的计算机科学家,多年来他们在数据库系统领域中做了大量的开创性工作。由他们撰写的《数据库系统实现》一书是关于数据库系统实现方面,内容最为全面的著述之一。书中对...

    了解IBM DB2数据库历史

    1975 年,他们进一步完善了 SQL 的实现方案,使得数据库查询和操作更加便捷。 1976 年,IBM System R 项目组发布了关于关系型数据库原型的论文,展示了关系数据库的实际应用。同时,Jim Gray 提出了数据库事务的...

    数据库系统原理PPT课件.ppt

    数据库系统原理的学习,包括了数据模型(如实体-联系模型、关系模型)、数据库设计(如概念设计、逻辑设计、物理设计)、SQL语言、事务处理、并发控制、恢复机制、安全性与完整性约束、数据库性能优化等内容。...

    NACA系列翼型数据库

    NACA,全称为美国国家航空咨询委员会(National Advisory Committee for Aeronautics),是20世纪上半叶美国的一个关键机构,其在航空科技领域做出了许多开创性的工作,其中包括对翼型的研究和标准化。 NACA翼型是...

    关于数据库系统实现的实例

    Ullman和Jennifer Widom是斯坦福大学著名的计算机科学家,多年来他们在数据库系统领域中做了大量的开创性工作。由他们撰写的《数据库系统实现》一书是关于数据库系统实现方面,内容最为全面的著述之一。书中对...

    数据库教父E.F.CODD.doc

    【E.F.CODD的贡献】 E.F.CODD,被誉为“数据库教父”,对数据库领域做出了划时代的贡献。...CODD的工作不仅开创了数据库的新纪元,还启发了后续众多的数据库理论和技术发展,他的贡献对IT行业产生了深远的影响。

    数据库系统概论课件第二章关系数据库.ppt

    这些操作构成了关系代数的基础,是数据库查询语言(如SQL)的基本构建块。 **2.3 关系的完整性** 关系的完整性规则确保了数据的一致性和正确性,主要包含实体完整性、参照完整性和用户定义的完整性。实体完整性...

    中华古诗词数据库

    它在继承唐诗的基础上,开创了更为细腻、更为注重音乐性的诗词风格。宋词在《中华古诗词数据库》中,呈现了1564位词人的创作风格与艺术追求,其中包括了豪放派的苏轼与辛弃疾,婉约派的李清照与周邦彦等。这些词人用...

    高级数据库 数据技术

    Clifford则在历史数据库领域做出了开创性工作,提出了历史关系数据模型(HRDM),将传统关系数据库视为历史数据库的特殊情况。这一时期标志着时态数据库正式形成。 接下来进入理论与模型探索阶段(1982年至1993年...

    SD数据库使用说明.ppt

    中国的高校用户广泛订阅了其中的1500多种期刊,每月下载量高达250万篇,体现了SD数据库的广泛影响力和实用性。 在学科覆盖方面,SD数据库几乎囊括了所有主要的科研领域,例如能源与动力、工程、环境科学、免疫学、...

    获图灵奖的三位数据库专家介绍.pptx

    随着计算机技术的飞速发展,数据库技术也在不断演进,包括分布式数据库、云计算数据库以及大数据处理等新兴领域,都离不开这三位先驱的开创性工作。他们对数据库理论和技术的贡献,确保了信息时代数据的有效存储、...

    2022年数据库系统概论之关系模型(共67张PPT).pptx

    同时,还会介绍如何利用关系模型进行数据库设计,包括数据完整性约束的设定,以及如何通过关系代数和关系演算进行复杂查询的表达。通过这些内容的学习,读者将能够深入理解关系模型的本质,从而更好地设计、管理和...

    数据库系统概论复习题目.doc

    Codd 首次提出了数据库系统的关系模型,开创了数据库关系方法和关系数据理论的研究。正确答案是 D,E. F. Codd。 13. 传统的集合运算是二目运算,包括交、差、并、笛卡尔积四种运算。正确答案是 A,笛卡尔积。 14...

    工学数据库引言PPT学习教案.pptx

    《工学数据库引言》课程内容全面,涵盖了数据库设计的基础过程、关系范式理论、SQL语言、查询优化、数据库设计原理、恢复技术、并发控制、安全性与完整性等多个方面。其中,重点和难点内容要求学生必须深入理解和...

Global site tag (gtag.js) - Google Analytics