动态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>
相关推荐
浪九天16 分钟前
Orcale、MySQL中参数类型的详解和运用场景(不带示例)
数据库·mysql·oracle
程序员阿鹏19 分钟前
jdbc批量插入数据到MySQL
java·开发语言·数据库·mysql·intellij-idea
橘猫云计算机设计2 小时前
基于Django的购物商城平台的设计与实现(源码+lw+部署文档+讲解),源码可白嫖!
java·数据库·spring boot·后端·django
2501_903238652 小时前
Spring Boot日志配置与环境切换实战
数据库·spring boot·后端·个人开发
梓沂2 小时前
审计级别未启用扩展模式导致查询 DBA_AUDIT_TRAIL 时 SQL_TEXT 列为空
数据库·sql·dba
caihuayuan43 小时前
PHP建立MySQL持久化连接(长连接)及mysql与mysqli扩展的区别
java·大数据·sql·spring
Smile丶凉轩3 小时前
数据库面试知识点总结
数据库·c++·mysql
RainbowSea4 小时前
9-1. MySQL 性能分析工具的使用——last\_query\_cost,慢查询日志
数据库·sql·mysql
Sui_Network4 小时前
Sui 如何支持各种类型的 Web3 游戏
大数据·数据库·人工智能·游戏·web3·区块链
ZKNOW甄知科技5 小时前
IT服务运营管理体系的常用方法论与实践指南(上)
大数据·数据库·人工智能