Mybatis从小白到小黑(六)Mybatis动态Sql详解

简介: 动态sql简单来讲就是我们能通过条件的设置生成不同的sql,在Mybatis中主要学习四种表达式即可:

微信搜索《Java鱼仔》,你离大厂更近了


(一)概述


mybatis官方中文网站对动态Sql的教程:mybatis.org/mybatis-3/z…


动态sql简单来讲就是我们能通过条件的设置生成不同的sql,在Mybatis中主要学习四种表达式即可:


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


(二)If


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



<selectid="SelectUserByMap"parameterType="map"resultType="map">    select * from user where 1=1
<iftest="id != null">        and id=#{id}
</if><iftest="name != null">        and name=#{name}
</if></select>

通过下面的方式进行查询

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

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

select*from user where1=1

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


你可能会奇怪我为什么要写一个1=1,这里后面会讲到。


(三)choose、when、otherwise


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


<selectid="SelectUserByChoose"parameterType="map"resultType="com.javayz.pojo.User">    select * from user where 1=1
<choose><whentest="id != null">            and id=#{id}
</when><whentest="name != null">            and name=#{name}
</when><otherwise>            and 1=1
</otherwise></choose></select>

(四)trim、where、set


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

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

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

select*from user whereand name=?

语法直接报错。


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


因此上面的内容我可以改成:

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

Set的实现和where类似,我们在更新时会用到set

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

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


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


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


<selectid="SelectUserByMap"parameterType="map"resultType="map">    select * from user
<trimprefix="where"prefixOverrides="and"><iftest="id != null">            and id=#{id}
</if><iftest="name != null">            and name=#{name}
</if></trim></select>

去除set末尾的逗号也可以使用trim

<trimprefix="SET"suffixOverrides=",">  ...
</trim>

(五)foreach


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


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

(六)总结


至此,我们就把mybatis的动态sql学习完毕了,总体来讲动态Sql的使用并不算复杂,关键还是多练,孰能生巧。

相关文章
|
5天前
|
JSON Java 数据库连接
MyBatis SQL 返回 resultType="map"
本文深入分析MyBatis中使用Map转VO的常见问题,指出JSON序列化转换方案虽可行但性能差、类型不安全、维护困难。推荐直接使用`resultType=&quot;VO&quot;`或`@Results`映射,提升性能10倍以上,增强可读性与可维护性,杜绝类型丢失风险,是更优的实践方案。
|
30天前
|
SQL XML Java
通过MyBatis的XML配置实现灵活的动态SQL查询
总结而言,通过MyBatis的XML配置实现灵活的动态SQL查询,可以让开发者以声明式的方式构建SQL语句,既保证了SQL操作的灵活性,又简化了代码的复杂度。这种方式可以显著提高数据库操作的效率和代码的可维护性。
142 18
|
6月前
|
SQL Java 数据库连接
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
|
5月前
|
SQL Java 数据库连接
MyBatis动态SQL字符串空值判断,这个细节99%的程序员都踩过坑!
本文深入探讨了MyBatis动态SQL中字符串参数判空的常见问题。通过具体案例分析,对比了`name != null and name != &#39;&#39;`与`name != null and name != &#39; &#39;`两种写法的差异,指出后者可能引发逻辑混乱。为避免此类问题,建议在后端对参数进行预处理(如trim去空格),简化MyBatis判断逻辑,提升代码健壮性与可维护性。细节决定成败,严谨处理参数判空是写出高质量代码的关键。
697 0
|
1月前
|
SQL Java 数据库连接
SSM相关问题-1--#{}和${}有什么区别吗?--Mybatis都有哪些动态sql?能简述一下动 态sql的执行原理吗?--Spring支持的几种bean的作用域 Scope
在MyBatis中,`#{}`是预处理占位符,可防止SQL注入,适用于大多数参数传递场景;而`${}`是直接字符串替换,不安全,仅用于动态表名、列名等特殊场景。二者在安全性、性能及使用场景上有显著区别。
57 0
|
4月前
|
SQL XML Java
菜鸟之路Day35一一Mybatis之XML映射与动态SQL
本文介绍了MyBatis框架中XML映射与动态SQL的使用方法,作者通过实例详细解析了XML映射文件的配置规范,包括namespace、id和resultType的设置。文章还对比了注解与XML映射的优缺点,强调复杂SQL更适合XML方式。在动态SQL部分,重点讲解了`&lt;if&gt;`、`&lt;where&gt;`、`&lt;set&gt;`、`&lt;foreach&gt;`等标签的应用场景,如条件查询、动态更新和批量删除,并通过代码示例展示了其灵活性与实用性。最后,通过`&lt;sql&gt;`和`&lt;include&gt;`实现代码复用,优化维护效率。
337 5
|
6月前
|
SQL Java 数据库连接
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
|
6月前
|
SQL 缓存 Java
框架源码私享笔记(02)Mybatis核心框架原理 | 一条SQL透析核心组件功能特性
本文详细解构了MyBatis的工作机制,包括解析配置、创建连接、执行SQL、结果封装和关闭连接等步骤。文章还介绍了MyBatis的五大核心功能特性:支持动态SQL、缓存机制(一级和二级缓存)、插件扩展、延迟加载和SQL注解,帮助读者深入了解其高效灵活的设计理念。
|
7月前
|
SQL XML Java
九、MyBatis动态SQL
九、MyBatis动态SQL
93 2
|
6月前
|
SQL XML Java
六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性
六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性
170 0