在复杂查询过程中,我们常常需要根据用户的选择决定查询条件,这里发生变化的
并不只是SQL 中的参数,包括Select 语句中所包括的字段和限定条件,都可能发生变
化。典型情况,如在一个复杂的组合查询页面,我们必须根据用户的选择和输入决定查
询的条件组合。
一个典型的页面如下:
对于这个组合查询页面,根据用户选择填写的内容,我们应为其生成不同的查询语
句。
如用户没有填写任何信息即提交查询请求,我们应该返回所有记录:
Select * from t_user;
如用户只在页面上填写了姓名“Erica”,我们应该生成类似:
Select * from t_user where name like ‘%Erica%’ ;
的SQL查询语句。
如用户只在页面上填写了地址“Beijing”,我们应该生成类似:
Select * from t_user where address like ‘%Beijing%”;
的SQL。
而如果用户同时填写了姓名和地址(”Erica”&’Beijing’),则我们应生成类似:
Select * from t_user where name like ‘%Erica%’ and address like ‘%Beijing%”
的SQL查询语句。
对于ibatis 这样需要预先指定SQL 语句的ORM 实现而言,传统的做法无非通过
if-else 语句对输入参数加以判定,然后针对用户选择调用不同的statement 定义。对于
上面这种简单的情况(两种查询条件的排列组合,共4 种情况)而言,statement 的重
复定义工作已经让人不厌其烦,而对于动辄拥有七八个查询条件,乃至十几个查询条件
的排列组合而言,琐碎反复的statement定义实在让人不堪承受。
考虑到这个问题,ibatis引入了动态映射机制,即在statement定义中,根据不同的
查询参数,设定对应的SQL语句。
还是以上面的示例为例:
<select id="getUsers"
parameterClass="user"
resultMap="get-user-result">
select
id,
name,
sex
from t_user
<dynamic prepend="WHERE">
<isNotEmpty prepend="AND" property="name">
(name like #name#)
</isNotEmpty>
<isNotEmpty prepend="AND" property="address">
(address like #address#)
</isNotEmpty>
</dynamic>
</select>
通过dynamic 节点,我们定义了一个动态的WHERE 子句。此WHERE 子句中将
可能包含两个针对name 和address 字段的判断条件。而这两个字段是否加入检索取决
于用户所提供的查询条件(字段是否为空[isNotEmpty])。
对于一个典型的Web程序而言,我们通过HttpServletRequest获得表单中的字段名
并将其设入查询参数,如:
user.setName(request.getParameter("name"));
user.setAddress(request.getParameter("address"));
sqlMap.queryForList("User.getUsers", user);
在执行queryForList("User.getUsers", user)时,ibatis 即根据配置文
件中设定的SQL动态生成规则,创建相应的SQL语句。
上面的示例中,我们通过判定节点isNotEmpty,指定了关于name 和address 属
性的动态规则:
<isNotEmpty prepend="AND" property="name">
(name like #name#)
</isNotEmpty>
这个节点对应的语义是,如果参数类的"name"属性非空(isNotEmpty,即非空
字符串””),则在生成的SQL Where字句中包括判定条件(name like #name#),其
中#name#将以参数类的name属性值填充。
Address属性的判定生成与name属性完全相同,这里就不再赘述。
这样,我们通过在statement 定义中引入dynamic 节点,很简单的实现了SQL 判
定子句的动态生成,对于复杂的组合查询而言,这将带来极大的便利。
判定节点的定义可以非常灵活,我们甚至可以使用嵌套的判定节点来实现复杂的动
态映射,如:
<isNotEmpty prepend="AND" property="name">
( name=#name#
<isNotEmpty prepend="AND" property="address">
address=#address#
</isNotEmpty>
)
</isNotEmpty>
这段定义规定,只有用户提供了姓名信息时,才能结合地址数据进行查询(如果只
提供地址数据,而将姓名信息忽略,将依然被视为全检索)。
Dynamic节点和判定节点中的prepend属性,指明了本节点中定义的SQL子句在
主体SQL中出现时的前缀。
如:
<dynamic prepend="WHERE">
<isNotEmpty prepend="AND" property="name">
(name like #name#)
</isNotEmpty>
<isNotEmpty prepend="AND" property="address">
(address like #address#)
</isNotEmpty>
</dynamic>
假设"name"属性的值为“Erica”, "address"属性的值为“Beijing”,则会
生成类似下面的SQL子句(实际运行期将生成带占位符的PreparedStatement,之
后再为其填充数据):
WHERE (name like ‘Beijing’) AND (address like ‘Beijing’)
其中WHERE 之后的语句是在dynamic 节点中所定义,因此以dynamic 节点的
prepend设置("WHERE")作为前缀,而其中的”AND”,实际上是address属性所对
应的isNotEmpty节点的prepend设定,它引领了对应节点中定义的SQL子句。至于
name属性对应的isNotEmpty节点,由于ibatis会自动判定是否需要追加prepend
前缀,这里(name like #name#)是WHERE 子句中的第一个条件子句,无需AND 前
缀,所以自动省略。
判定节点并非仅限于isNotEmpty,ibatis中提供了丰富的判定定义功能。
判定节点分两类:
? 一元判定
一元判定是针对属性值本身的判定,如属性是否为NULL,是否为空值等。
上面示例中isNotEmpty就是典型的一元判定。
一元判定节点有:
节点名 描述
<isPropertyAvailable> 参数类中是否提供了此属性
<isNotPropertyAvailable> 与<isPropertyAvailable>相反
<isNull> 属性值是否为NULL
<isNotNull> 与<isNull>相反
<isEmpty> 如果属性为Collection或者String,其size是否<1,
如果非以上两种类型,则通过
String.valueOf(属性值)
获得其String类型的值后,判断其size是否<1
<isNotEmpty> 与<isEmpty>相反。
? 二元判定
二元判定有两个判定参数,一是属性名,而是判定值,如
<isGreaterThan prepend="AND" property="age"
compareValue="18">
(age=#age#)
</isGreaterThan>
其中,property="age"指定了属性名”age”,compareValue=”18”指明
了判定值为”18”。
上面判定节点isGreaterThan 对应的语义是:如果age 属性大于
18(compareValue),则在SQL中加入(age=#age#)条件。
二元判定节点有:
节点名 属性值与compareValues的关系
<isEqual> 相等。
<isNotEqual> 不等。
<isGreaterThan> 大于
<isGreaterEqual> 大于等于
<isLessThan> 小于
<isLessEqual> 小于等于

ibatis动态查询的更多相关文章

  1. ibatis动态查询条件

    ibatis的调试相对困难,出错的时候主要依据是log4生成的log文件和出错提示,这方面要能比较熟练的看懂. 下面这个配置基本上包含了最复杂的功能:分页\搜索\排序\缓存\传值Hash表\返回has ...

  2. ibatis 动态查询

    http://www.iteye.com/topic/393042最近做了很多动态的查询,尤其是排序,以及一些状态字段,所以就做了一个总的动态查询,以不变应万变,呵呵 ibatis 里面的sql代码: ...

  3. ibatis动态多条件查询及模糊查询(oracle,mysql,sql)

    首先是模糊查询的问题,开始时我使用如下条件:select * from user where name like '%#value#%'. 可是怎么也不行,好像还报错了.后来在网上找到了解决方法,就是 ...

  4. Ibatis动态(dynamic)查询

     Ibatis的动态查询使得数据操作变得非常的灵活,下次举出了常用的动态查询的属性信息: Ibatis配置信息 <!-- Dynamic Sql --> <typeAlias a ...

  5. ibatis Dynamic总结(ibatis使用安全的拼接语句,动态查询)

    ibatis中使用安全的拼接语句,动态查询,ibatis比JDBC的优势之一,安全高效 说明文字在注释中 一.引入 一个小例子  <select id="selectAllProduc ...

  6. ibatis 取消查询动态列的缓存

    ibatis在查询结果列不确定(或是动态变化)的情况下,会因为列缓存的原因导致变化后的列数据查不出来 解决方法是: select标签有个属性remapResults,该属性默认值为false,设置成r ...

  7. 转:ibatis动态sql

    转:ibatis动态sql 直接使用JDBC一个非常普遍的问题就是动态SQL.使用参数值.参数本身和数据列都是动态SQL,通常是非常困难的.典型的解决办法就是用上一堆的 IF-ELSE条件语句和一连串 ...

  8. Ibatis动态拼装sql,常用标签总结及举栗子。

    今天得到项目经理一项任务,就是拼装sql,第一次见到,不是太懂,赶紧回来睡一觉再说,由于这次的项目orm使用的是ibatis框架,所以需要使用动态拼装sql,或者是ognl语言,这门语言不是专属于ib ...

  9. IBATIS动态SQL(1)

    转:IBATIS动态SQL 直接使用JDBC一个非常普遍的问题就是动态SQL.使用参数值.参数本身和数据列都是动态SQL,通常是非常困难的.典型的解决办法就是用上一堆的IF-ELSE条件语句和一连串的 ...

随机推荐

  1. 怎样按字母顺序(ABCDEF)动态添加控件

    考试系统中题库设计时,我想动态添加选项,顺序按ABCDEF这样,点击一下按钮添加A(radiobutton),再点击添加B,如此依次添加.本人比较菜,求达人写一个方法. private void bu ...

  2. arguments.callee 调用函数自身用法----JSON.parse()和JSON.stringify()前端js数据转换json格式

    arguments.callee 调用函数自身用法 arguments.callee 在哪一个函数中运行,它就代表哪个函数. 一般用在匿名函数中. 在匿名函数中有时会需要自己调用自己,但是由于是匿名函 ...

  3. Vim复制粘贴

    用了快一年Vim了,今天想要将vim里的一句话复制到浏览器里,结果捣鼓了半天.汗! 解决方案: 在vim中按“V”进入可视模式,选中要复制的文字 接下来要按3个键“+y(引号.加号.字母y),这样要复 ...

  4. [JS进阶] 编写可维护性代码 (1)

    今天的web应用大至成千上万行的javascript代码,执行各种复杂的过程,这种演化让我们开发者必须得对可维护性有一定的认识!编写可维护性代码很重要,很多情况下我们是以他人的工作成果为基础,确保代码 ...

  5. JAVA 编码机制

    先看例子: public class Test { public static void main(String[] args) { char han = '永'; System.out.printl ...

  6. Java String.split()注意点

    //String[] aa = "aaa|bbb|ccc".split("|");//错误 String[] aa = "aaa|bbb|ccc&qu ...

  7. CSS3 transition 属性 过渡效果

    <!DOCTYPE html> <html> <head> <style> div { width:100px; height:100px; backg ...

  8. iOS 进阶 第十一天(0411)

    0411 UItaBbar的结构 每一个数组都有一个方法,那就是下面这个,如下图所示: 如果想看系统控件是怎么构成的,那么就采用遍历其子控件的方式来做,如上一图中所示 在iOS7及其以后的系统里,控制 ...

  9. 【软件工程-Teamwork 2】必应词典软件手机版测试报告

    测试人员:聂健(N).居玉皓(J).吴渊渊(Wy).汪仁贵(Wr).吕佳辉(L).杜冰磊(D) 测试软件:必应词典软件手机版 版本:2.2.0版本(Android) 引言: 我们的测评报告的主体主要分 ...

  10. 论坛类应用双Tableview翻页效果实现

    作为一名篮球爱好者,经常使用虎扑体育,虎扑体育应用最核心的部分就是其论坛功能,无论哪个版块,论坛都是其核心,而其论坛部分的实现又别具一格,它以两个tableview的形式翻页滚动显示,而不是常见的那种 ...