MyBatis动态SQL表达式详解

目录
  • if
  • choose when otherwise
  • trim where set
  • foreach
  • sql片段

动态 sql 简单来讲就是我们能通过条件的设置生成不同的 sql,MyBatis 中常用的动态 sql 表达式主要是有五种:

  • if
  • choose (when, otherwise)
  • trim, where, set
  • foreach
  • sql

if

动态 sql 中最常见的场景是根据条件查询,比如要实现一个查询语句,当不传任何参数时查询所有用户,当传了 id 或者 name 时根据条件进行查询,就可以这样写:

<select id="selectUserByMap" parameterType="map" resultType="user">
    select * from user where 1=1
    <if test="id != null and id!=''">
        and id=#{id}
    </if>
    <if test="name != null and name!=''">
        and name=#{name}
    </if>
</select>

对应的 mapper 接口如下:

public interface UserMapper {
    List<User> selectUserByMap(Map<String,Object> param);
    void updateUser(Map<String,Object> param);
}

对应的 Java 代码如下:

Map<String,String> map=new HashMap<String, String>();
map.put("id","1");
map.put("name","javayz");
List<User> users = mapper.selectUserByMap(map);

当 map 中什么都不传时,sql 语句变为:

select * from user where 1=1

当传了 id 或 name 时,分别执行对应的查询。

choose when otherwise

choose 的使用很像 Java 中的 switch 语法,当满足第一个 when 条件时,就不去看后续的条件,如果条件都不满足,则执行 otherwise:

<select id="selectUserByChoose" parameterType="map" resultType="user">
    select * from user where 1=1
    <choose>
        <when test="id != null">
            and id=#{id}
        </when>
        <when test="name != null">
            and name=#{name}
        </when>
        <otherwise>
            and 1=1
        </otherwise>
    </choose>
</select>

trim where set

还记得前面的语法中都写了 where 1=1 吗,至于为什么这样写,目的在于让语法能顺利执行,以 if 语句为例:如果不写 1=1,语法就会变成下面这样:

<select id="selectUserByMap" parameterType="map" resultType="user">
    select * from user where
    <if test="id != null">
        id=#{id}
    </if>
    <if test="name != null">
        and name=#{name}
    </if>
</select>

这个时候如果满足了第一个 if 条件,那不会有问题,但是如果只满足第二个条件,语句就会变成:

select * from user where and name=?

语法直接报错。

MyBatis 提供了一种标签来代替 1=1 的写法,where 标签只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

<select id="selectUserByMap" parameterType="map" resultType="user">
    select * from user
    <where>
        <if test="id != null">
            and id=#{id}
        </if>
        <if test="name != null">
            and name=#{name}
        </if>
    </where>
</select>

set 的语法和 where 类似,在更新时会用到 set:

<update id="updateUser" parameterType="map">
    update user
    <set>
        <if test="name != null">name =#{name},</if>
    </set>
    where id = #{id}
</update>

使用 where 时会用自动去替换掉 and 或者 or,而使用 set 时会动态地在行首插入 SET 关键字,并会删掉额外的逗号。

使用 trim 可以用于去除拼接 sql 时的 and、or 关键字或者逗号等等。

之前使用 where 标签去除了最开始的 and 关键字,用 trim 也同样可以实现:

<select id="selectUserByMap" parameterType="map" resultType="map">
    select * from user
    <trim prefix="where" prefixOverrides="and">
        <if test="id != null">
            and id=#{id}
        </if>
        <if test="name != null">
            and name=#{name}
        </if>
    </trim>
</select>

foreach

foreach 在需要对集合进行遍历的场景中使用很广泛,尤其是在 in 语句中,比如下面这条语句:

select * from user where id in (1,2,3,4)

通过 foreach 实现方式如下,foreach 中的 ids 可以是参数传入的一个 List 集合:

<select id="selectUserByForeach" parameterType="map" resultType="User">
    select * from user where id in
        <foreach collection="ids" item="id" index="index" open="(" separator="," close=")">
            #{id}
        </foreach>
</select>

sql片段

通过 sql 片段标签,可以将重复的 sql 提取出来,使用时通过 include 引用即可。

<sql id="select_user_where">
    <if test="id != null and id!=''">
        and id=#{id}
    </if>
    <if test="name != null and name!=''">
        and name=#{name}
    </if>
</sql>
<select id="selectUserByMap" parameterType="map" resultType="user">
    select * from user where 1=1
    <include refid="select_user_where">
</select>

到此这篇关于MyBatis动态SQL表达式详解的文章就介绍到这了,更多相关MyBatis动态SQL内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Mybatis中xml的动态sql实现示例

    目录 动态SQL简介 一.#{}与${}区别#{}表示一个占位符,使用占位符可以防止sql注入, 二.传递包装类型 三.动态sql—类型 四.动态sql—详解 (一)if 语句处理 (二)choose (when,otherwize)语句处理 (三)trim 语句处理 (四)where 语句处理 (五)foreach 语句处理 动态SQL简介 动态 SQL 是 MyBatis 的强大特性之一. 如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接

  • Mybatis如何实现@Select等注解动态组合SQL语句

    目录 一.背景说明 二.实现方案 三. 实现自定义注解 1.自定义Select注解 2.自定义Select in注解 3.自定义Update的注解 4.自定义Insert的注解 同理 四.注意事项&遇到的一些坑 五.总结 一.背景说明 由于以前在项目中一直使用sqlmap.xml进行mybatis语句的编写和实现,其xml实现动态更新和查询较为方便,而目前由于技术框架所定,采用@Select.@Insert等注解方式来实现对应的持久化操作(MyBatis提供了简单的Java注解,使得我们可以不配

  • MyBatis动态sql查询及多参数查询方式

    目录 MyBatis动态sql 动态sql处理简单的多参数查询 动态sql处理更新功能 动态sql扩展 动态sql处理集合参数 foreach标签处理数组类型参数 foreach标签处理List类型参数 foreach标签处理Map类型参数 分页功能 基于MySql的分页查询 MyBatis动态sql 动态sql处理简单的多参数查询 常用标签 标签 说明 if 条件判断,与java中的if语句类似 where 为sql语句动态添加where关键字 choose 条件判断,这是一个组合标签,需要与

  • Mybatis多表查询与动态SQL特性详解

    目录 1.较复杂的查询操作 1.1 参数占位符 #{} 和 ${} 1.2SQL注入 1.3like查询 1.4resultType与resultMap 1.4多表查询 1.4.1一对一表映射 1.4.2一对多表映射 2.动态SQL 2.1if标签 2.2trim标签 2.3where标签 2.4set标签 2.5foreach标签 总结 1.较复杂的查询操作 1.1 参数占位符 #{} 和 ${} #{}:预处理符,如将id=#{2}替换为id=?,然后使用2替换?. ${}:替换符,如将id

  • MyBatis在注解上使用动态SQL方式(@select使用if)

    目录 MyBatis在注解上使用动态SQL 1.用script标签包围 2.用Provider去实现SQL拼接 3.说明 MyBatis xml注释SQL的注意事项 注意事项 MyBatis在注解上使用动态SQL 1.用script标签包围 然后像xml语法一样书写 @Select({"<script>",                 "SELECT * FROM tbl_order",                 "WHERE 1=1

  • MyBatis @Select注解介绍:基本用法与动态SQL拼写方式

    目录 1.@Select注解基本用法 2.@Select注解动态SQL拼写 @Select动态参数参考 1.@Select注解基本用法 @Select注解的目的是为了取代xml中的select标签,只作用于方法上面. 下面看一下@Select注解的源码介绍: @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Select {     String[] value(); } 从上述可以

  • Mybatis的动态Sql组合模式详情

    目录 前言 Component角色 Composite角色 Left类角色 TextSqlNode TrimSqlNode IfSqlNode StaticTextSqlNode 总结 前言 当同一类型的很多对象组成一个树结构的时候,可以考虑使用组合模式,组合模式涉及三个类: Component接口:定义树的各个节点的一些操作 Left类:这个是树的叶子结点,实现Component接口,对于节点的管理它不去实现,只实现业务逻辑 Composite类:这个是树的非叶子节点,实现Component接

  • MyBatis动态SQL表达式详解

    目录 if choose when otherwise trim where set foreach sql片段 动态 sql 简单来讲就是我们能通过条件的设置生成不同的 sql,MyBatis 中常用的动态 sql 表达式主要是有五种: if choose (when, otherwise) trim, where, set foreach sql if 动态 sql 中最常见的场景是根据条件查询,比如要实现一个查询语句,当不传任何参数时查询所有用户,当传了 id 或者 name 时根据条件进

  • MyBatis 动态SQL全面详解

    目录 前言 动态sql 1.先看一下模块目录结构 2.物理建模和逻辑建模 3. 引入依赖 4.全局配置文件 5.sql共性抽取文件 6.mapper接口 if 静态sql: 动态sql: where 用if标签的动态sql: where和if的动态sql: trim trim的动态sql trim标签: set trim的动态sql: set的动态sql set标签的作用: choose.when.otherwise 动态sql foreach 1.动态sql 2.动态sql 批量查询:fore

  • Mybatis动态SQL实例详解

    动态SQL 什么是动态SQL? MyBatis的官方文档中是这样介绍的? 动态 SQL 是 MyBatis 的强大特性之一.如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号.利用动态 SQL,可以彻底摆脱这种痛苦. 使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性. 如果你之前用过 JS

  • MyBatis 执行动态 SQL语句详解

    大家基本上都知道如何使用 MyBatis 执行任意 SQL,使用方法很简单,例如在一个 XXMapper.xml 中: <select id="executeSql" resultType="map"> ${_parameter} </select> 你可以如下调用: sqlSession.selectList("executeSql", "select * from sysuser where enabled

  • Mybatis中输入输出映射与动态Sql图文详解

    一.输入映射 我们通过配置parameterType的值来指定输入参数的类型,这些类型可以是简单数据类型.POJO.HashMap等数据类型 1.简单类型 2.POJO包装类型 ①这是单表查询的时候传入的POJO包装类型,即可以直接传入实体类,但是当多表查询的时候,就需要自定义POJO类型 ②我们使用自定义POJO类型来具体的了解一下 先设计 包装类型如下,其中UserPOJO是除了User本身之外的添加的其他跟User相关的属性的包装类,UserVo是用于视图层面的包装类型,同样也是作为Map

  • MyBatis 动态SQL和缓存机制实例详解

    有的时候需要根据要查询的参数动态的拼接SQL语句 常用标签: - if:字符判断 - choose[when...otherwise]:分支选择 - trim[where,set]:字符串截取,其中where标签封装查询条件,set标签封装修改条件 - foreach: if案例 1)在EmployeeMapper接口文件添加一个方法 public Student getStudent(Student student); 2)如果要写下列的SQL语句,只要是不为空,就作为查询条件,如下所示,这样

  • MyBatis动态Sql之if标签的用法详解

    最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 本篇博客主要讲解如何使用if标签生成动态的Sql,主要包含以下3个场景: 1.根据查询条件实现动态查询 2.根据参数值实现动态更新某些列 3.根据参数值实现动态插入某些列 1. 使用if标签实现动态查询 假设有这样1个需求:根据用户的输入条件来查询用户列表,如果输入了用户名,就根据用户名模糊查询,如果输入了邮箱,就根据邮箱精确查询,如果同时输入了

  • MyBatis动态SQL标签的用法详解

    1.MyBatis动态SQL MyBatis 的强大特性之一便是它的动态 SQL,即拼接SQL字符串.如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦.拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号.利用动态 SQL 这一特性可以彻底摆脱这种痛苦. 通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意的 SQL 映射语句中. 动态 SQL 元素和

  • Mybatis动态SQL之if、choose、where、set、trim、foreach标记实例详解

    动态SQL就是动态的生成SQL. if标记 假设有这样一种需求:查询用户,当用户名不等于"admin"的时候,我们还需要密码为123456. 数据库中的数据为: MyBatisConfig.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

随机推荐