https://ibatis.apache.org/docs/dotnet/datamapper/ch03s09.html

3.9. Dynamic SQL

A very common problem with working directly with ADO is dynamic SQL. It is normally very difficult to work with SQL statements that change not only the values of parameters, but which parameters and columns are included at all. The typical solution is usually a mess of conditional if-else statements and horrid string concatenations. The desired result is often a query by example, where a query can be built to find objects that are similar to the example object. The iBATIS DataMapper API provides a relatively elegant solution that can be applied to any mapped statement element. Here is a simple example:

Example 3.56. A simple dynamic select sttatement, with two possible outcomes

<select id="dynamicGetAccountList" cacheModel="account-cache" parameterClass="Account" resultMap="account-result" >
select * from ACCOUNT
<isGreaterThan prepend="and" property="Id" compareValue="0">
where ACC_ID = #Id#
</isGreaterThan>
order by ACC_LAST_NAME
</select>

In the above example, there are two possible statements that could be created depending on the state of the Id property of the parameter object. If the Id parameter is greater than 0, then the statement will be created as follows:

select * from ACCOUNT where ACC_ID = ?

Or if the Id parameter is 0 or less, the statement will look as follows.

select * from ACCOUNT

The immediate usefulness of this might not become apparent until a more complex situation is encountered. For example, the following is a somewhat more complex example.

Example 3.57. A complex dynamic select statement, with 16 possible outcomes

<select id="dynamicGetAccountList" parameterClass="Account" resultMap="account-result" >
select * from ACCOUNT
<dynamic prepend="WHERE">
<isNotNull prepend="AND" property="FirstName">
( ACC_FIRST_NAME = #FirstName#
<isNotNull prepend="OR" property="LastName">
ACC_LAST_NAME = #LastName#
</isNotNull>
)
</isNotNull>
<isNotNull prepend="AND" property="EmailAddress">
ACC_EMAIL like #EmailAddress#
</isNotNull>
<isGreaterThan prepend="AND" property="Id" compareValue="0">
ACC_ID = #Id#
</isGreaterThan>
</dynamic>
order by ACC_LAST_NAME
</select>

Depending on the situation, there could be as many as 16 different SQL queries generated from the above dynamic statement. To code the if-else structures and string concatenations could get quite messy and require hundreds of lines of code.

Using dynamic statements is as simple as inserting some conditional tags around the dynamic parts of your SQL. For example:

Example 3.58. Creating a dynamic statement with conditional tags

<statement id="someName" parameterClass="Account" 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>

In the above statement, the <dynamic> element demarcates a section of the SQL that is dynamic. The dynamic element is optional and provides a way to manage a prepend in cases where the prepend ("WHERE") should not be included unless the contained conditions append to the statement. The statement section can contain any number of conditional elements (see below) that will determine whether the contained SQL code will be included in the statement. All of the conditional elements work based on the state of the parameter object passed into the query. Both the dynamic element and the conditional elements have a "prepend" attribute. The prepend attribute is a part of the code that is free to be overridden by the a parent element's prepend if necessary. In the above example the "where" prepend will override the first true conditional prepend. This is necessary to ensure that the SQL statement is built properly. For example, in the case of the first true condition, there is no need for the AND, and in fact it would break the statement. The following sections describe the various kinds of elements, including Binary Conditionals, Unary Conditionals, and Iterate.

3.9.1. Binary Conditional Elements

Binary conditional elements compare a property value to a static value or another property value. If the result is true, the body content is included in the SQL query.

3.9.1.1. Binary Conditional Attributes:

prepend – the overridable SQL part that will be prepended to the statement (optional)
property – the property to be compared (required)
compareProperty – the other property to be compared (required or compareValue)
compareValue – the value to be compared (required or compareProperty)

Table 3.7. Binary conditional attributes

Element Description
<isEqual> Checks the equality of a property and a value, or another property. Example Usage:

<isEqual prepend="AND"
property="status"
compareValue="Y">
MARRIED = ‘TRUE'
</isEqual>
<isNotEqual> Checks the inequality of a property and a value, or another property. Example Usage:

<isNotEqual prepend="AND"
property="status"
compareValue="N">
MARRIED = ‘FALSE'
</isNotEqual>
<isGreaterThan> Checks if a property is greater than a value or another property. Example Usage:

<isGreaterThan prepend="AND"
property="age"
compareValue="18">
ADOLESCENT = ‘FALSE'
</isGreaterThan>
<isGreaterEqual> Checks if a property is greater than or equal to a value or another property. Example Usage:

<isGreaterEqual prepend="AND"
property="shoeSize"
compareValue="12">
BIGFOOT = ‘TRUE'
</isGreaterEqual>
<isLessEqual> Checks if a property is less than or equal to a value or another property. Example Usage:

<isLessEqual prepend="AND"
property="age"
compareValue="18">
ADOLESCENT = ‘TRUE'
</isLessEqual>

3.9.2. Unary Conditional Elements

Unary conditional elements check the state of a property for a specific condition.

3.9.2.1. Unary Conditional Attributes:

prepend – the overridable SQL part that will be prepended to the statement (optional)
property – the property to be checked (required)

Table 3.8. Unary conditional attributes

Element Description
<isPropertyAvailable> Checks if a property is available (i.e is a property of the parameter object). Example Usage:

<isPropertyAvailable property="id" >
ACCOUNT_ID=#id#
</isPropertyAvailable>
<isNotPropertyAvailable> Checks if a property is unavailable (i.e not a property of the parameter object). Example Usage:

<isNotPropertyAvailable property="age" >
STATUS='New'
</isNotEmpty>
<isNull> Checks if a property is null. Example Usage:

<isNull prepend="AND" property="order.id" >
ACCOUNT.ACCOUNT_ID = ORDER.ACCOUNT_ID(+)
</isNotEmpty>
<isNotNull> Checks if a property is not null. Example Usage:

<isNotNull prepend="AND" property="order.id" >
ORDER.ORDER_ID = #order.id#
</isNotEmpty>
<isEmpty> Checks to see if the value of a Collection, String property is null or empty ("" or size() < 1). Example Usage:

<isEmpty property="firstName" >
LIMIT 0, 20
</isNotEmpty>
<isNotEmpty> Checks to see if the value of a Collection, String property is not null and not empty ("" or size() < 1). Example Usage:

<isNotEmpty prepend="AND" property="firstName" >
FIRST_NAME LIKE '%$FirstName$%'
</isNotEmpty>

3.9.3. Parameter Present Elements

These elements check for parameter object existence.

3.9.3.1. Parameter Present Attributes:

prepend – the overridable SQL part that will be prepended to the statement (optional)

Table 3.9. Testing to see if a parameter is present

Element Description
<isParameterPresent> Checks to see if the parameter object is present (not null).

<isParameterPresent prepend="AND">
EMPLOYEE_TYPE = #empType#
</isParameterPresent>
<isNotParameterPresent> Checks to see if the parameter object is not present (null). Example Usage:

<isNotParameterPresent prepend="AND">
EMPLOYEE_TYPE = ‘DEFAULT'
</isNotParameterPresent>

3.9.4. Iterate Element

This tag will iterate over a collection and repeat the body content for each item in a List

3.9.4.1. Iterate Attributes:

prepend – the overridable SQL part that will be prepended to the statement (optional)
property – a property of type IList that is to be iterated over (required)
open – the string with which to open the entire block of iterations, useful for brackets (optional)
close – the string with which to close the entire block of iterations, useful for brackets (optional)
conjunction – the string to be applied in between each iteration, useful for AND and OR (optional)

Table 3.10. Creating a list of conditional clauses

Element Description
<iterate> Iterates over a property that is of type IList Example Usage:

<iterate prepend="AND" property="UserNameList"
open="(" close=")" conjunction="OR">
username=#UserNameList[]#
</iterate>

Note: It is very important to include the square brackets[] at the end of the List property name when using the Iterate element. These brackets distinguish this object as an List to keep the parser from simply outputting the List as a string.

3.9.5. Simple Dynamic SQL Elements

Despite the power of the full Dynamic Mapped Statement API discussed above, sometimes you just need a simple, small piece of your SQL to be dynamic. For this, SQL statements and statements can contain simple dynamic SQL elements to help implement dynamic order by clauses, dynamic select columns or pretty much any part of the SQL statement. The concept works much like inline parameter maps, but uses a slightly different syntax. Consider the following example:

Example 3.59. A dynamic element that changes the collating order

<statement id="getProduct" resultMap="get-product-result">
select * from PRODUCT order by $preferredOrder$
</statement>

In the above example the preferredOrder dynamic element will be replaced by the value of the preferredOrder property of the parameter object (just like a parameter map). The difference is that this is a fundamental change to the SQL statement itself, which is much more serious than simply setting a parameter value. A mistake made in a Dynamic SQL Element can introduce security, performance and stability risks. Take care to do a lot of redundant checks to ensure that the simple dynamic SQL elements are being used appropriately. Also, be mindful of your design, as there is potential for database specifics to encroach on your business object model. For example, you may not want a column name intended for an order by clause to end up as a property in your business object, or as a field value on your server page.

Simple dynamic elements can be included within <statements> and come in handy when there is a need to modify the SQL statement itself. For example:

Example 3.60. A dynamic element that changes the comparison operator

<statement id="getProduct" resultMap="get-product-result">
SELECT * FROM PRODUCT
<dynamic prepend="WHERE">
<isNotEmpty property="Description">
PRD_DESCRIPTION $operator$ #Description#
</isNotEmpty>
</dynamic>
</statement>

In the above example the operator property of the parameter object will be used to replace the $operator$ token. So if the operator property was equal to LIKE and the description property was equal to %dog%, then the SQL statement generated would be:

  SELECT * FROM PRODUCT WHERE PRD_DESCRIPTION LIKE ‘%dog%'

Dynamic SQL--官方文档的更多相关文章

  1. Spark SQL 官方文档-中文翻译

    Spark SQL 官方文档-中文翻译 Spark版本:Spark 1.5.2 转载请注明出处:http://www.cnblogs.com/BYRans/ 1 概述(Overview) 2 Data ...

  2. mybatis 动态 SQL 官方文档

    MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦.例如拼接时要确保不能忘记添加必要的空格,还要注意去掉 ...

  3. Spark SQL官方文档阅读--待完善

    1,DataFrame是一个将数据格式化为列形式的分布式容器,类似于一个关系型数据库表. 编程入口:SQLContext 2,SQLContext由SparkContext对象创建 也可创建一个功能更 ...

  4. 看MySQL官方文档的示例SQL有感

    [背景] 周末比较闲,我这个人又没有什么爱好,当然了读书除外:前一些天我一个同事说:“你一个dba想去写一本“django”书,合适吗?” 我想也是,一个人不能忘了本,所以MySQL还是要好好的搞一搞 ...

  5. 入门常用SQL及官方文档的使用

    SQL语句基础理论 SQL是操作和检索关系型数据库的标准语言,标准SQL语句可用于操作关系型数据库. 5大主要类型: ①DQL(Data Query Language,数据查询语言)语句,主要由于se ...

  6. MyBatis3-topic-01 -安装/下载/官方文档 -执行输入一条已经映射的sql语句

    mybatis XML 映射配置文件 (官方文档) -对象工厂(objectFactory) -配置环境(environments) -映射器(mappers) 本地IDEA搭建/测试步骤 创建数据库 ...

  7. Mysql优化(出自官方文档) - 第一篇(SQL优化系列)

    Mysql优化(出自官方文档) - 第一篇 目录 Mysql优化(出自官方文档) - 第一篇 1 WHERE Clause Optimization 2 Range Optimization Skip ...

  8. Spring Data Commons 官方文档学习

    Spring Data Commons 官方文档学习   -by LarryZeal Version 1.12.6.Release, 2017-07-27 为知笔记版本在这里,带格式. Table o ...

  9. hbase官方文档(转)

    FROM:http://www.just4e.com/hbase.html Apache HBase™ 参考指南  HBase 官方文档中文版 Copyright © 2012 Apache Soft ...

  10. HBase 官方文档

    HBase 官方文档 Copyright © 2010 Apache Software Foundation, 盛大游戏-数据仓库团队-颜开(译) Revision History Revision ...

随机推荐

  1. VC 无标题栏对话框移动(在OnLButtonDown里再次发送消息)

    操作系统:Windows 7软件环境:Visual C++ 2008 SP1本次目的:实现无框移动 所谓的无标题栏对话框,是基于对话框的工程,对话框属性Border设置为None,对话框如下所示: 为 ...

  2. ruby 方法重载

    class MyClass def sayHello return "hello from MyClass" end def sayGoodbye return "Goo ...

  3. plsql 高效原则

    sql优化是项复杂的工作,不能简单而论,但是在平时书写脚本时的一些细节可以大大提高我们编写代码的效率,提高代码质量. 以下这些规则部分是我的经验,部分是网络资料,整理后在我平时的工作中运用后得到验证的 ...

  4. OLEDB和ODBC的区别(优缺点)

    ODBC是一种连接数据库的开放标准,OLEDB(对象链接和嵌入数据库)位于ODBC层与应用程序之间. 在你的ASP页面里,ADO是位于OLEDB之上的应用程序. 你的ADO调用先被送到OLEDB,然后 ...

  5. BrnShop开源网上商城第四讲:自定义插件

    重要通知:BrnShop企业版NOSQL设计(基于Redis)已经开源!源码内置于最新版的BrnShop中,感兴趣的园友可以去下载来看看.官网地址:www.brnshop.com. 好了现在进入今天的 ...

  6. TreeMap源码解析

    1.TreeMap介绍 TreeMap是一个通过红黑树实现有序的key-value集合. TreeMap继承AbstractMap,也即实现了Map,它是一个Map集合 TreeMap实现了Navig ...

  7. spring(7)--注解式控制器的数据验证、类型转换及格式化

    7.1.简介 在编写可视化界面项目时,我们通常需要对数据进行类型转换.验证及格式化. 一.在Spring3之前,我们使用如下架构进行类型转换.验证及格式化: 流程: ①:类型转换:首先调用Proper ...

  8. C# using Sendkey function to send a key to another application

    If notepad is already started, you should write: // import the function in your class [DllImport (&q ...

  9. [liu yanling]测试用例作用

    ⒈指导测试的实施 测试用例主要适用于集成测试.系统测试和回归测试.在实施测试时测试用例作为测试的标准,测试人员一定要按照测试用例严格按用例项目和测试步骤逐一实施测试.并对测试情况记录在测试用例管理软件 ...

  10. oracle logminer全解析

    今天写篇原创的,把在工作中遇到的logminer问题总结下 (1)简介: logminer 工具即可以用来分析在线,也可以用来分析离线日志文件,即可以分析本身自己数据库的重作日志文件,也可以用来分析其 ...