MyBatis 的动态 SQL 包括以下几种元素:

详细的使用参考官网文档:http://www.mybatis.org/mybatis-3/zh/dynamic-sql.html

本章内容简单描述这些动态 SQL 在使用的过程中需要注意的地方。

choose, when, otherwise

比如我们要实现如下功能:

  • 当学生姓名不为空,则只用学生姓名作为条件查询
  • 当学生性别不为空,则只用学生性别作为条件查询
  • 当学生姓名和学生性别都为空,则要求学生学生证件号不为空

针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

<select id="listByConditions" parameterType="studentQuery" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from t_student
<where>
<choose>
<when test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</when>
<when test="sex != null">
AND sex = #{sex}
</when>
<otherwise>
AND selfcard_no is not null
</otherwise>
</choose>
</where>
</select>

trim, where, set

比如下面的动态 SQL 有什么问题?

<select id="listByConditions" parameterType="studentQuery" resultMap="BaseResultMap">
SELECT id, name, sex, selfcard_no, note
FROM t_student
WHERE
<if test="ids != null and ids.size() > 0">
id IN
<foreach collection="ids" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="sex != null">
AND sex = #{sex}
</if>
<if test="selfcardNo != null">
AND selfcard_no = #{selfcardNo}
</if>
</select>

如果这些条件没有一个能匹配上会发生什么?最终这条 SQL 会变成这样:

SELECT id, name, sex, selfcard_no, note
FROM t_student
WHERE

这样会导致 SQL 语句执行失败。如果仅仅第二个条件匹配又会怎样?这条 SQL 最终会是这样:

SELECT id, name, sex, selfcard_no, note
FROM t_student
WHERE
AND name LIKE CONCAT('%', 'a', '%')

这个查询也会失败。

MyBatis 提供了 <where> 元素可以解决上面的问题,将上面的动态 SQL 改成如下形式。

<select id="listByConditions" parameterType="studentQuery" resultMap="BaseResultMap">
SELECT id, name, sex, selfcard_no, note
FROM t_student
<where>
<if test="ids != null and ids.size() > 0">
AND id IN
<foreach collection="ids" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="sex != null">
AND sex = #{sex}
</if>
<if test="selfcardNo != null">
AND selfcard_no = #{selfcardNo}
</if>
</where>
</select>

foreach

实现批量新增功能,动态 SQL 如下:

<insert id="batchInsertByNoAutoInc" parameterType="list">
<selectKey keyProperty="id" resultType="long" order="BEFORE">
select if(max(id) is null, 1, max(id) + 2) as newId from t_student
</selectKey>
insert into t_student (name, sex, selfcard_no, note)
values
<foreach collection="list" item="item" index="index" separator=",">
(
#{item.name,jdbcType=VARCHAR},
#{item.sex,jdbcType=TINYINT},
#{item.selfcardNo,jdbcType=BIGINT},
#{item.note,jdbcType=VARCHAR}
)
</foreach>
</insert>

批量新增的操作需要确保 list 中必须有值。

MyBatis 实用篇

MyBatis 概念

MyBatis 示例-简介

MyBatis 示例-类型处理器

MyBatis 示例-传递多个参数

MyBatis 示例-主键回填

MyBatis 示例-动态 SQL

MyBatis 示例-联合查询

MyBatis 示例-缓存

MyBatis 示例-插件

MyBatis 示例-动态 SQL的更多相关文章

  1. MyBatis的动态SQL详解

    MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑,本文详解mybatis的动态sql,需要的朋友可以参考下 MyBatis 的一个强大的特性之一通常是它 ...

  2. MyBatis的动态SQL详解-各种标签使用

    MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑. MyBatis中用于实现动态SQL的元素主要有: if choose(when,otherwise) ...

  3. 利用MyBatis的动态SQL特性抽象统一SQL查询接口

    1. SQL查询的统一抽象 MyBatis制动动态SQL的构造,利用动态SQL和自定义的参数Bean抽象,可以将绝大部分SQL查询抽象为一个统一接口,查询参数使用一个自定义bean继承Map,使用映射 ...

  4. MyBatis中动态SQL元素的使用

    掌握MyBatis中动态SQL元素的使用 if choose(when,otherwise) trim where set foreach <SQL>和<include> 在应 ...

  5. Java-MyBatis:MyBatis 3 动态 SQL

    ylbtech-Java-MyBatis:MyBatis 3 动态 SQL 1.返回顶部 1. 动态 SQL MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架 ...

  6. 一分钟带你了解下MyBatis的动态SQL!

    MyBatis的强大特性之一便是它的动态SQL,以前拼接的时候需要注意的空格.列表最后的逗号等,现在都可以不用手动处理了,MyBatis采用功能强大的基于OGNL的表达式来实现,下面主要介绍下. 一. ...

  7. Mybatis中动态SQL语句中的parameterType不同数据类型的用法

    Mybatis中动态SQL语句中的parameterType不同数据类型的用法1. 简单数据类型,    此时#{id,jdbcType=INTEGER}中id可以取任意名字如#{a,jdbcType ...

  8. Mybatis解析动态sql原理分析

    前言 废话不多说,直接进入文章. 我们在使用mybatis的时候,会在xml中编写sql语句. 比如这段动态sql代码: <update id="update" parame ...

  9. mybatis 使用动态SQL

    RoleMapper.java public interface RoleMapper { public void add(Role role); public void update(Role ro ...

随机推荐

  1. linux提权方法(不断总结更新)

    目录 1.suid提权 2.rbash绕过 3.git提权 4.Linux Kernel 4.4.x (Ubuntu 16.04) - 'double-fdput()' bpf(BPF_PROG_LO ...

  2. Qt:使用Model-View,动态的加载显示数据

    共有 main.cpp, Widget.h, Widget.cpp, Widget.ui, MyModel.h, MyModel.cpp 六个文件. 可从此下载整个工程文件: /Files/biao/ ...

  3. mysql数据库每个表的备份脚本

    对mysql数据库中的每张表进行按日期备份,思想是:先把每张表的表名取出取出,然后通过for循环去对每个表进行按日期备份 [root@ZFVM-APP-- backup]# vim dataname. ...

  4. hive进阶 技巧

    1.日期格式转换(将yyyymmdd转换为yyyy-mm-dd) select from_unixtime(unix_timestamp('20180905','yyyymmdd'),'yyyy-mm ...

  5. [oracle]oracle表在什么情况下会被锁住(转载)

    DML锁又可以分为,行锁.表锁.死锁 行锁:当事务执行数据库插入.更新.删除操作时,该事务自动获得操作表中操作行的排它锁. 表级锁:当事务获得行锁后,此事务也将自动获得该行的表锁(共享锁),以防止其它 ...

  6. Windows Bat 之For 循环

        Windows Bat 之For 循环 1. For 循环基本用法. 1.1 格式 在cmd窗口中: FOR %variable IN (set) DO command [command-pa ...

  7. 免费下载 SetupVPN CRX 3.7.0 for Chrome OR QQ浏览器

    免费下载 SetupVPN CRX 3.7.0 for Chrome OR QQ浏览器 Lifetime Free VPN(微劈嗯) 下载setupvpn 3.7.0的crx文件, 打开chrome的 ...

  8. Jenkins 搭建企业实战案例 (发布与回滚)

    让我们的代码部署变得easy,不再难,Jenkins是一个可扩展的持续集成引擎,是一个开源软件项目,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能.Jenkins非常易于安装和配置,简单易用 ...

  9. python3 __mian和__name__的区别

    1.新建 test.py 模块: def GetModuleName(): print('__name__ = ', __name__) def PrintName(): print('PrintNa ...

  10. es6 是否包含字符串判断

    字符串查找类 接下来介绍一些可以通过 ES5 PolyFill的方法,但是现在 ES6 原生实现了 Method Param Return Description includes() 需要验证是否被 ...