动态sql

本文参考mybatis看这一篇就够了,简单全面一发入魂

动态SQL

可以根据具体的参数条件,来对SQL语句进行动态拼接。

比如在以前的开发中,由于不确定查询参数是否存在,许多人会使用类似于where 1 = 1 来作为前缀,然后后面用AND 拼接要查询的参数,这样,就算要查询的参数为空,也能够正确执行查询,如果不加1 = 1,则如果查询参数为空,SQL语句就会变成SELECT * FROM student where ,SQL不合法。

mybatis里的动态标签主要有

if

XML 复制代码
<!-- 示例 -->
<select id="find" resultType="student" parameterType="student">
        SELECT * FROM student WHERE age >= 18
        <if test="name != null and name != ''">
            AND name like '%${name}%'
        </if>
</select>

当满足test条件时,才会将<if>标签内的SQL语句拼接上去

where

<where>标签在MyBatis中用于动态生成SQL语句中的WHERE子句。它可以根据条件表达式的结果自动地添加或省略WHERE关键字,并且能够处理多个条件之间的逻辑关系(AND、OR)。

<where>标签通常与<if><choose><when><otherwise>等条件判断标签一起使用,以根据不同的条件构建不同的SQL WHERE子句。

如果WHERE之后是以AND或OR开头,会自动将其删掉

下面是一些使用<where>标签的例子:

  1. 使用<where>标签包含一个条件:
XML 复制代码
<select id="findActiveUsers" resultType="User">
  SELECT * FROM users
  <where>
    status = #{status}
  </where>
</select>

如果status参数不为null,<where>标签会生成WHERE status = #{status};如果status为null,则不会生成任何内容,避免了额外的WHERE关键字。

2.使用<where>标签包含多个条件:

XML 复制代码
<select id="findUsersByNameAndAge" resultType="User">
  SELECT * FROM users
  <where>
    <if test="name != null">
      name = #{name}
    </if>
    <if test="age != null">
      AND age = #{age}
    </if>
  </where>
</select>

在这个例子中,如果nameage参数都不为null,<where>标签会生成WHERE name = #{name} AND age = #{age}。如果只有name不为null,它会生成WHERE name = #{name}。如果两个参数都为null,则不会生成任何内容。

3.使用<where>标签处理复杂的条件逻辑:

XML 复制代码
<select id="findUsersByComplexCondition" resultType="User">
  SELECT * FROM users
  <where>
    <if test="name != null">
      name = #{name}
    </if>
    <if test="age != null">
      <choose>
        <when test="age > 18">
          AND age > 18
        </when>
        <otherwise>
          AND age = #{age}
        </otherwise>
      </choose>
    </if>
    <if test="status != null">
      AND status = #{status}
    </if>
  </where>
</select>

在这个例子中,<where>标签结合了<if><choose><when><otherwise>标签来构建复杂的条件逻辑。

<where>标签的优点是它能够自动处理WHERE关键字的存在与否,以及条件之间的逻辑关系,使得生成的SQL语句更加准确和简洁。

<choose>, <when>, <otherwise>

<choose>, <when>, <otherwise>标签是MyBatis中用于条件判断的标签,类似于Java中的switch-case语句。它们通常与<if><else>标签一起使用,用于根据不同的条件生成不同的SQL片段。

下面是<choose>, <when>, <otherwise>标签的使用示例:

XML 复制代码
<select id="findUsersByStatus" resultType="User">
  SELECT * FROM users
  <where>
    <choose>
      <when test="status == 'active'">
        AND status = 'active'
      </when>
      <when test="status == 'inactive'">
        AND status = 'inactive'
      </when>
      <otherwise>
        AND status IS NULL
      </otherwise>
    </choose>
  </where>
</select>

在这个例子中,我们根据用户的状态(status)来查询用户数据。如果状态为"active",则生成AND status = 'active';如果状态为"inactive",则生成AND status = 'inactive';否则,生成AND status IS NULL

<choose>标签用于包含多个条件判断,它内部可以包含一个或多个<when>标签和一个可选的<otherwise>标签。每个<when>标签都对应一个条件表达式,当该条件满足时,会执行对应的SQL片段。如果所有<when>标签的条件都不满足,且存在<otherwise>标签,则会执行<otherwise>标签内的SQL片段。

通过使用<choose>, <when>, <otherwise>标签,我们可以更灵活地构建动态SQL语句,根据不同的条件生成不同的SQL片段,提高代码的可读性和可维护性。

trim

<where>标签可以用<trim>标签代替

可以通过<trim>标签更加灵活地对SQL进行定制

XML 复制代码
<trim prefix="WHERE" prefixOverrides="AND | OR">
   ...
</trim>

set

在至少有一个子元素返回了SQL语句时,才会向SQL语句中添加SET,并且如果SET之后是以,开头的话,会自动将其删掉

<set>标签相当于如下的<trim>标签

XML 复制代码
<trim prefix="SET" prefixOverrides=",">
   ...
</trim>

实际上在mybatis源码,也能看到trim与set,where标签的父子关系

foreach

用来做迭代拼接的,通常会与SQL语句中的IN查询条件结合使用,注意,到parameterType为List(链表)或者Array(数组),后面在引用时,参数名必须为list或者array。如在foreach标签中,collection属性则为需要迭代的集合,由于入参是个List,所以参数名必须为list

XML 复制代码
<select id="batchFind" resultType="student" parameterType="list">
        SELECT * FROM student WHERE id in
        <foreach collection="list" item="item" open="(" separator="," close=")">
          #{item}
        </foreach>
</select>

sql

可将重复的SQL片段提取出来,然后在需要的地方,使用<include>标签进行引用

XML 复制代码
<select id="findUser" parameterType="user" resultType="user">
	SELECT * FROM user
	<include refid="whereClause"/>
</select>

<sql id="whereClause">
     <where>
         <if test="user != null">
         	AND username like '%${user.name}%'
         </if>
     </where>
</sql>
相关推荐
知识分享小能手14 分钟前
Redis入门学习教程,从入门到精通,Redis 数据操作:知识点详解与代码实战(2)
数据库·redis·学习
m0_6625779721 分钟前
Python迭代器(Iterator)揭秘:for循环背后的故事
jvm·数据库·python
似水明俊德25 分钟前
12-C#
开发语言·数据库·oracle·c#
FirstFrost --sy1 小时前
MySQL关于表的操作
数据库·mysql
青槿吖2 小时前
【保姆级教程】Spring事务控制通关指南:XML+注解双版本,避坑指南全奉上
xml·java·开发语言·数据库·sql·spring·mybatis
浪潮IT馆2 小时前
Windows 达梦 8(DM8)数据库完整安装教程 + 命令行导入 .dmp 文件完整指南
数据库·windows
Dylan~~~2 小时前
Redis MCP Server:让 AI 拥有“持久记忆“的革命性方案
数据库·人工智能·redis
小小怪7502 小时前
超越Python:下一步该学什么编程语言?
jvm·数据库·python
Y001112362 小时前
Day8-MySQL-多表查询-1
数据库·sql·mysql
2501_945423543 小时前
数据分析与科学计算
jvm·数据库·python