ibatis的文档中,关于动态SQL的举例如下:
<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">
分享到:
相关推荐
例如,在`<select>`标签中,通过`<dynamic prepend="where module">`可以构建带有条件的SQL查询语句,其中的`prepend`属性用于指定条件语句的前缀。这种方式不仅简化了代码,还提高了SQL语句的可读性和可维护性。 ...
本文将详细介绍 ibatis 中 Dynamic SQL 的使用方法,特别关注 `<dynamic>` 标签及其相关的子标签。 #### 二、Dynamic SQL 标签概述 Dynamic SQL 在 ibatis 中主要通过以下几种标签实现: 1. **`<dynamic>`**:用于...
`<dynamic>`标签是iBATIS动态标签的核心,它允许在其内部包含一系列的条件标签,根据不同的条件来决定哪些部分应该被插入到最终的SQL语句中。`<dynamic>`标签有三个主要属性: 1. `prepend`: 在动态内容前添加的字符...
根据给定的文件信息,以下是对“Ibatis常用SQL语句”的详细解析,涵盖了一系列Ibatis在数据操作中的应用实例。 ### Ibatis简介 Ibatis是一个支持普通SQL查询、存储过程以及高级映射的优秀持久层框架。Ibatis可以让...
在iBatis中,SQL语句是通过XML文件来配置的。下面是16个常用的iBatis SQL语句,涵盖了基本的CRUD(Create、Read、Update、Delete)操作。 1. 删除语句 在iBatis中,删除语句可以使用`<delete>`元素。例如: ```xml...
在使用iBatis进行数据库操作的过程中,可能会遇到各种各样的问题。这些问题往往由于iBatis错误信息的隐晦性而难以快速定位与解决。本文将根据所提供的标题、描述及部分内容,详细阐述在使用iBatis时可能遇到的一些...
iBatis 是一款优秀的持久层框架,它将 SQL 映射到 Java 对象,简化了 JDBC 编程过程中的繁琐操作,提高了开发效率。iBatis 的核心功能包括 SQL 映射、动态 SQL 生成等,它通过配置文件或者注解的形式来实现 SQL 语句...
在 iBatis 中,动态查询条件是通过 `<dynamic>` 元素来实现的,该元素可以根据参数的值来生成不同的 SQL 语句。 在 iBatis 中,参数可以是基本类型、字符串、集合等,它们可以通过 `#` symbols 来传递给 SQL 语句。...
通过这个入门教程,你应该对Ibatis的基本使用有了初步了解,包括配置SQL Map、编写动态SQL、创建Java接口和实体类、与Spring的整合以及事务管理。进一步的学习和实践将帮助你更熟练地运用Ibatis解决实际开发中的数据...
以上就是关于iBATIS 2的基本介绍,它在处理数据库操作时提供了极大的便利性,通过将SQL语句与Java代码解耦,使得开发更加高效且易于维护。对于深入理解iBATIS的工作原理,阅读提供的文档《iBATIS-SqlMaps-2_en.pdf》...
iBatis 是一款轻量级的Java持久层框架,它主要负责将数据库操作与业务逻辑解耦,使得开发者可以更加专注于SQL和业务代码的编写。本文档将详细讲解iBatis的核心概念、快速入门以及高级特性。 ### iBatis 快速启动 #...
在ibatis中,实现复杂的`AND` 和 `OR` 联合查询可以通过动态SQL来完成。动态SQL允许在运行时动态地构建SQL语句,从而实现更加灵活的查询功能。 #### 四、示例解析 根据提供的部分代码,我们可以详细分析如何在...
在Ibatis中,动态查询是解决复杂查询需求的关键特性,它允许我们在SQL语句中根据实际的业务逻辑和用户输入动态地生成查询条件。在上述的描述中,我们看到一个典型的场景,即根据用户在页面上填写的不同内容,我们...
ibatis可以使用简单的XML或注解进行配置和原始映射,在代码内映射语句执行SQL。 ### 错误1:参数类型与属性不匹配 在ibatis中,`parameterClass`属性用于指定传递给SQL语句的参数类型。例如,在给定的部分内容中:...
iBATIS,作为一款优秀的持久层框架,提供了强大的动态SQL功能,解决了直接使用JDBC时编写复杂动态SQL的难题。本文将深入探讨iBATIS动态注入的相关知识点。 iBATIS动态SQL主要通过XML映射文件中的特定标签实现,允许...
在Ibatis中,复杂查询通常涉及到多个表的联接、条件动态拼接、子查询以及各种数据类型的处理。...在实际开发中,这种灵活性使得Ibatis能够适应各种复杂的业务场景,同时保持SQL语句的清晰和可读性。
**知识点3:** 使用 Map 作为参数传递到 SQL 语句中,可以更加灵活地处理多条件组合查询。 1. **使用 `<isPropertyAvailable>` 判断属性的有效性:** - `<isPropertyAvailable>` 用于判断 Map 中是否存在某个键。 ...
在这个例子中,`<dynamic>`元素用于包裹整个动态部分,`prepend="WHERE"`表明在动态生成的SQL语句前会自动添加WHERE关键字。`<isNotNull>`和`<isNotEmpty>`则分别用于判断参数是否非空和字符串是否非空,进而决定...
根据提供的文件信息,我们可以深入探讨ibatis框架中的动态SQL元素及其使用方法。下面将详细介绍标题、描述以及部分内容中涉及的关键知识点。 ### ibatis 动态代理DTD #### 标题解释 - **ibatis**: 是一个开源的...