`
songbin0201
  • 浏览: 323276 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

ibatis的dynamicSQL中,关于prepend的使用

阅读更多
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">
分享到:
评论
1 楼 卖火柴的老特工 2013-11-28  
学习了,dynamic的prepend属性会覆盖第一个条件为真的prepend属性,条件里的prepend属性所在的参数满足条件,则会前置拼接sql

相关推荐

    ibatis常用sql语句

    例如,在`&lt;select&gt;`标签中,通过`&lt;dynamic prepend="where module"&gt;`可以构建带有条件的SQL查询语句,其中的`prepend`属性用于指定条件语句的前缀。这种方式不仅简化了代码,还提高了SQL语句的可读性和可维护性。 ...

    ibatis dynamic 用法

    本文将详细介绍 ibatis 中 Dynamic SQL 的使用方法,特别关注 `&lt;dynamic&gt;` 标签及其相关的子标签。 #### 二、Dynamic SQL 标签概述 Dynamic SQL 在 ibatis 中主要通过以下几种标签实现: 1. **`&lt;dynamic&gt;`**:用于...

    iBATIS动态标签

    `&lt;dynamic&gt;`标签是iBATIS动态标签的核心,它允许在其内部包含一系列的条件标签,根据不同的条件来决定哪些部分应该被插入到最终的SQL语句中。`&lt;dynamic&gt;`标签有三个主要属性: 1. `prepend`: 在动态内容前添加的字符...

    Ibatis常用sql语句

    根据给定的文件信息,以下是对“Ibatis常用SQL语句”的详细解析,涵盖了一系列Ibatis在数据操作中的应用实例。 ### Ibatis简介 Ibatis是一个支持普通SQL查询、存储过程以及高级映射的优秀持久层框架。Ibatis可以让...

    ibatis16个常用sql语句

    在iBatis中,SQL语句是通过XML文件来配置的。下面是16个常用的iBatis SQL语句,涵盖了基本的CRUD(Create、Read、Update、Delete)操作。 1. 删除语句 在iBatis中,删除语句可以使用`&lt;delete&gt;`元素。例如: ```xml...

    ibatis出错调试心得

    在使用iBatis进行数据库操作的过程中,可能会遇到各种各样的问题。这些问题往往由于iBatis错误信息的隐晦性而难以快速定位与解决。本文将根据所提供的标题、描述及部分内容,详细阐述在使用iBatis时可能遇到的一些...

    Ibatis查询语句里,可以使用多表查询

    iBatis 是一款优秀的持久层框架,它将 SQL 映射到 Java 对象,简化了 JDBC 编程过程中的繁琐操作,提高了开发效率。iBatis 的核心功能包括 SQL 映射、动态 SQL 生成等,它通过配置文件或者注解的形式来实现 SQL 语句...

    ibatis_动态查询条件

    在 iBatis 中,动态查询条件是通过 `&lt;dynamic&gt;` 元素来实现的,该元素可以根据参数的值来生成不同的 SQL 语句。 在 iBatis 中,参数可以是基本类型、字符串、集合等,它们可以通过 `#` symbols 来传递给 SQL 语句。...

    IBATIS SQL Maps 入门教程.pdf

    通过这个入门教程,你应该对Ibatis的基本使用有了初步了解,包括配置SQL Map、编写动态SQL、创建Java接口和实体类、与Spring的整合以及事务管理。进一步的学习和实践将帮助你更熟练地运用Ibatis解决实际开发中的数据...

    API ibatis2

    以上就是关于iBATIS 2的基本介绍,它在处理数据库操作时提供了极大的便利性,通过将SQL语句与Java代码解耦,使得开发更加高效且易于维护。对于深入理解iBATIS的工作原理,阅读提供的文档《iBATIS-SqlMaps-2_en.pdf》...

    iBatis文档\ibatis.doc

    iBatis 是一款轻量级的Java持久层框架,它主要负责将数据库操作与业务逻辑解耦,使得开发者可以更加专注于SQL和业务代码的编写。本文档将详细讲解iBatis的核心概念、快速入门以及高级特性。 ### iBatis 快速启动 #...

    ibatis and和or联合查询 .doc

    在ibatis中,实现复杂的`AND` 和 `OR` 联合查询可以通过动态SQL来完成。动态SQL允许在运行时动态地构建SQL语句,从而实现更加灵活的查询功能。 #### 四、示例解析 根据提供的部分代码,我们可以详细分析如何在...

    Ibatis高级使用讲解

    在Ibatis中,动态查询是解决复杂查询需求的关键特性,它允许我们在SQL语句中根据实际的业务逻辑和用户输入动态地生成查询条件。在上述的描述中,我们看到一个典型的场景,即根据用户在页面上填写的不同内容,我们...

    ibatis的错误总结

    ibatis可以使用简单的XML或注解进行配置和原始映射,在代码内映射语句执行SQL。 ### 错误1:参数类型与属性不匹配 在ibatis中,`parameterClass`属性用于指定传递给SQL语句的参数类型。例如,在给定的部分内容中:...

    ibatis动态注入

    iBATIS,作为一款优秀的持久层框架,提供了强大的动态SQL功能,解决了直接使用JDBC时编写复杂动态SQL的难题。本文将深入探讨iBATIS动态注入的相关知识点。 iBATIS动态SQL主要通过XML映射文件中的特定标签实现,允许...

    Ibatis复杂查询语句.doc

    在Ibatis中,复杂查询通常涉及到多个表的联接、条件动态拼接、子查询以及各种数据类型的处理。...在实际开发中,这种灵活性使得Ibatis能够适应各种复杂的业务场景,同时保持SQL语句的清晰和可读性。

    ibatis的动态查询

    **知识点3:** 使用 Map 作为参数传递到 SQL 语句中,可以更加灵活地处理多条件组合查询。 1. **使用 `&lt;isPropertyAvailable&gt;` 判断属性的有效性:** - `&lt;isPropertyAvailable&gt;` 用于判断 Map 中是否存在某个键。 ...

    IBATIS动态查询语句.doc

    在这个例子中,`&lt;dynamic&gt;`元素用于包裹整个动态部分,`prepend="WHERE"`表明在动态生成的SQL语句前会自动添加WHERE关键字。`&lt;isNotNull&gt;`和`&lt;isNotEmpty&gt;`则分别用于判断参数是否非空和字符串是否非空,进而决定...

    ibatis 动态代理dtd

    根据提供的文件信息,我们可以深入探讨ibatis框架中的动态SQL元素及其使用方法。下面将详细介绍标题、描述以及部分内容中涉及的关键知识点。 ### ibatis 动态代理DTD #### 标题解释 - **ibatis**: 是一个开源的...

Global site tag (gtag.js) - Google Analytics