简介
MyBatis动态SQL是一种强大的功能,它允许你在SQL语句中使用条件逻辑,从而根据不同的条件生成不同的SQL语句。这在处理复杂的查询场景时非常有用,比如根据不同的查询条件动态构建SQL语句。
实现方式
MyBatis动态SQL主要通过以下几种元素来实现:
<if>标签
用于条件判断,如果条件为真,则包含其中的SQL片段。
<select id="findActiveBlogWithTitleLike" resultType="Blog">
SELECT * FROM BLOG
WHERE state = 'ACTIVE'
<if test="title != null">
AND title like #{title}
</if>
</select>
<choose>
, <when>
, <otherwise>
:标签
类似于Java中的switch
语句,用于多条件选择。
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG
WHERE state = 'ACTIVE'
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
<where>标签
用于简化SQL语句中的WHERE
子句,自动处理AND
或OR
的前缀。
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG
<where>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</where>
</select>
<set>标签
用于动态生成UPDATE
语句中的SET
子句。
<update id="updateBlog" parameterType="Blog">
UPDATE BLOG
<set>
<if test="title != null">
title = #{title},
</if>
<if test="author != null">
author = #{author},
</if>
</set>
WHERE id = #{id}
</update>
<foreach>标签
用于遍历集合,常用于生成IN
子句或批量操作。
<select id="selectPostIn" resultType="Post">
SELECT *
FROM POST P
WHERE ID IN
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
<trim>标签
用于自定义前缀和后缀,可以替代<where>
和<set>
元素。
属性:
-
prefix
: 在包含的内容前加上前缀。-
示例:
<trim prefix="WHERE">
会在包含的内容前加上WHERE
。
-
-
prefixOverrides
: 覆盖掉包含的内容前的字符串。-
示例:
<trim prefixOverrides="AND |OR ">
会去掉包含的内容前的AND
或OR
。
-
-
suffix
: 在包含的内容后加上后缀。-
示例:
<trim suffix=";">
会在包含的内容后加上;
。
-
-
suffixOverrides
: 覆盖掉包含的内容后的字符串。-
示例:
<trim suffixOverrides=",">
会去掉包含的内容后的,
。
-
<select id="findActiveBlogLike" resultType="Blog">
SELECT * FROM BLOG
<trim prefix="WHERE" prefixOverrides="AND |OR ">
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
OR author_name like #{author.name}
</if>
</trim>
</select>
<bind>标签
它允许你在SQL语句中创建一个临时变量,这个变量可以在当前的上下文中使用。<bind>
标签通常用于处理一些需要重复使用的表达式或值,从而避免重复编写相同的代码。
处理模糊查询
<select id="findBlogByTitle" resultType="Blog">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'"/>
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
</select>
-
name
属性:定义变量的名称,这个名称可以在当前的SQL语句中使用。 -
value
属性:定义变量的值,可以是任何有效的OGNL表达式。
业务演示
如下图所示,现在要完成对姓名,登录名,性别,角色分别作为不同条件的查询,同时也能够多条件一起查询和模糊查询姓名,登录名。
业务代码展示
<select id="userlist" resultMap="userListRole">
SELECT u.*,r.id rid,r.name rname from user u LEFT JOIN user_role ur ON u.id=ur.uid left JOIN role r on r.id=ur.rid
<trim prefix="where" prefixOverrides="and | or">
<if test="name != '' and name != null">
<bind name="name" value="'%'+name+'%'"/>
and u.name like #{name}
</if>
<if test="loginname != '' and loginname != null">
<bind name="loginname" value="'%'+loginname+'%'"/>
and u.loginname like #{loginname}
</if>
<if test="sex != '' and sex != null">
<bind name="sex" value="'%'+sex+'%'"/>
and u.sex like #{sex}
</if>
<if test="rid!='0'.toString()">
and r.id = #{rid}
</if>
</trim>
limit #{pageIndex},#{pageLast}
</select>
这段代码中用到的标签有<trim>,<if>,<bind>。
trim标签用于根据实际情况自动在sql语句前加上where条件,并且根据实际情况自动省略掉sql语句前的and或者or。
if标签用于判断,只有当参数满足条件时才会将标签里面的sql语句拼接完整,bind标签用于给参数加百分号,实现模糊查询,第一个值代表参数名,第二个值代表要对参数进行的处理。
结果展示
当首次进入页面,什么也不查询的时,输出的sql语句及携带的参数如下:
当进行查询性别为男的用户时,输出的sql语句及携带的参数如下:
当查询性别为男,角色为用户时, 输出的sql语句及携带的参数如下: