ibatis的dynamicSQL中,关于prepend的使用
来源:互联网 发布:电波消逝之日 知乎 编辑:程序博客网 时间:2024/05/21 08:52
ibatis的文档中,关于动态SQL的举例如下:
当需要使用根据传入参数的值来动态组装SQL时,可以使用dynamic标签。
dynamic元素可以包含多个条件比较元素,并且按照条件比较元素的表述对参数值进行比较,来组装动态SQL。
这里主要的条件比较元素包含isGreaterThan、isNotNull、isEmpty……
dynamic元素和条件比较元素,都是组成动态SQL的一部分,其中的prepend属性根据实际情况的需要辅助的组装动态SQL。
以上面的statement为例:
1)dynamic的prepend只要检测到第一个为“真”的条件比较元素,则覆盖其prepend属性并组装where关键字为动态SQL的一部分。
2)isNotNull的prepend只要检测到参数值满足比较条件,则前置组装and关键字为动态SQL的一部分。
注意一点:上面的例子中,ibtis文档中说 - dynamic元素中的prepend属性“where”将覆盖第一个为“真”的条件比较元素(即isGreaterThan)的prepend属性
按照这个理解,则第一个为“真”的条件比较元素(即isGreaterThan)的prepend属性是不需要的,或者“and”是不需要的,(ibatis文档中的原文是 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) 则修改上述例子为
事实上,这样修改的结果导致最终SQL 变为
“select * from ACCOUNT where ACC_ID = #id# ACC_LAST_NAME = #lastName#”
明显是有问题的。
跟踪源码发现,ibatis在检测sqlTag的时候,调用了如下方法
dynamic要覆盖第一个为“真”的条件比较元素的prepend属性,首先需要检测该tag的prepend是否可用(tag.isPrependAvailable()),如果不可用的话,即便该比较条件为“真”,则不会覆盖,只是单独的添加该比较条件元素下的SQL
由此可以看出,prepend可用的前提是prepend属性值已经设置,并且长度>0。
这样的话就不难理解上述修改后的statement,为何SQL变更为“select * from ACCOUNT where ACC_ID = #id# ACC_LAST_NAME = #lastName#”?因为ACC_LAST_NAME = #lastName#的前置prepend,被作为第一个为真的比较条件给删除了。
正确的写法应该是
或者
- <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>
当需要使用根据传入参数的值来动态组装SQL时,可以使用dynamic标签。
dynamic元素可以包含多个条件比较元素,并且按照条件比较元素的表述对参数值进行比较,来组装动态SQL。
这里主要的条件比较元素包含isGreaterThan、isNotNull、isEmpty……
dynamic元素和条件比较元素,都是组成动态SQL的一部分,其中的prepend属性根据实际情况的需要辅助的组装动态SQL。
以上面的statement为例:
1)dynamic的prepend只要检测到第一个为“真”的条件比较元素,则覆盖其prepend属性并组装where关键字为动态SQL的一部分。
2)isNotNull的prepend只要检测到参数值满足比较条件,则前置组装and关键字为动态SQL的一部分。
注意一点:上面的例子中,ibtis文档中说 - dynamic元素中的prepend属性“where”将覆盖第一个为“真”的条件比较元素(即isGreaterThan)的prepend属性
按照这个理解,则第一个为“真”的条件比较元素(即isGreaterThan)的prepend属性是不需要的,或者“and”是不需要的,(ibatis文档中的原文是 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) 则修改上述例子为
- <statement id="someName" parameterClass="Account" resultMap="account-result" >
- select * from ACCOUNT
- <dynamic prepend="where">
- <isGreaterThan 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 变为
“select * from ACCOUNT where ACC_ID = #id# ACC_LAST_NAME = #lastName#”
明显是有问题的。
跟踪源码发现,ibatis在检测sqlTag的时候,调用了如下方法
- public void pushRemoveFirstPrependMarker(SqlTag tag) {
- if(tag.getHandler() instanceof DynamicTagHandler) {
- // this was added to retain default behavior
- if(tag.isPrependAvailable()) {
- removeFirstPrependStack.addFirst(
- new RemoveFirstPrependMarker(tag,true));
- } else {
- removeFirstPrependStack.addFirst(
- new RemoveFirstPrependMarker(tag,false));
- }
- ……
dynamic要覆盖第一个为“真”的条件比较元素的prepend属性,首先需要检测该tag的prepend是否可用(tag.isPrependAvailable()),如果不可用的话,即便该比较条件为“真”,则不会覆盖,只是单独的添加该比较条件元素下的SQL
- public boolean isPrependAvailable() {
- return prependAttr != null && prependAttr.length() > 0;
- }
由此可以看出,prepend可用的前提是prepend属性值已经设置,并且长度>0。
这样的话就不难理解上述修改后的statement,为何SQL变更为“select * from ACCOUNT where ACC_ID = #id# ACC_LAST_NAME = #lastName#”?因为ACC_LAST_NAME = #lastName#的前置prepend,被作为第一个为真的比较条件给删除了。
正确的写法应该是
- <isGreaterThan prepend="and" property="id" compareValue="0">
或者
- <isGreaterThan prepend=" " property="id" compareValue="0">
0 0
- ibatis的dynamicSQL中,关于prepend的使用
- Ibatis 关于DynamicSql源码的解读
- 主题:ibatis中prepend的小用法
- ibatis 的语句中 isEqual、property、compareValue,prepend 都代表什么意思
- iBatis prepend iterate 标签,in字句的一点总结
- js中append和prepend的用法
- Ruby中include / extend / prepend的区别
- 关于iBatis的缓存使用
- 关于iBatis的缓存使用
- 关于iBatis的缓存使用
- 关于ibatis 的使用 queryForObject
- 关于ibatis使用中遇到的问题 和解决方案
- 关于iBatis/iBatis.net中parameterMap使用的一个技巧(亲自实践)
- ibatis中CDATA的使用
- ibatis中iterate的使用
- Ibatis中iterate的使用
- ibatis中CDATA的使用
- ibatis 中blob的使用
- struts2中使用ognl传递值
- Mac中的常用命令
- 软件工程网络工程第三章联合训练(AC代码和详细解释)(c语言描述)
- Android简单自定义圆形和水平ProgressBar
- JAVA从菜鸟【入门】到新手【实习】一一10月上半月总结与十月下半月规划
- ibatis的dynamicSQL中,关于prepend的使用
- Hybrid computing using a neural network with dynamic external memory(可微神经计算机)阅读
- C3P0替代hibernate管理连接池
- 读书笔记之:鸟哥Linux私房菜(基础篇)
- POJ 3265 DP
- MySql DOS中操作的常用SQL语句
- POJ 3271 BFS (大坑)
- 网桥帧的转发与转发表的建立算法
- [C++]前置声明和头文件