【Mybatis】动态SQL详解

文章目录

动态SQL

<if> 用于条件判断,决定是否包含某个SQL片段。

if+set

<set> 用于动态生成 SET 子句,自动处理多余的逗号。

xml 复制代码
<!-- 更新用户信息 -->
<update id="edit" >
    UPDATE smbms_user
    <set>
        <if test="userCode != null">userCode = #{userCode},</if>
        <if test="userName != null">userName = #{userName},</if>
        <if test="gender != null">gender = #{gender},</if>
        <if test="birthday != null">birthday = #{birthday},</if>
        <if test="address != null">address = #{address}</if>
    </set>
    WHERE id = #{id}
</update>

if+where

<where> 用于动态生成 WHERE 子句,自动处理多余的ANDOR关键字。

xml 复制代码
<!-- 多条件分页查询 -->
<select id="findAll" resultType="User">
    select id,userCode,userName,gender,birthday,address,creationDate
    from smbms_user
    <where>
        <if test="userName != null and userName != ''">
            and userName like concat('%', #{userName}, '%')
        </if>
        <if test="address != null and address != ''">
            and address like concat('%', #{address}, '%')
        </if>
        <if test="beginDate != null and beginDate != ''">
            and creationDate &gt;= #{beginDate}
        </if>
        <if test="endDate != null and endDate != ''">
            and creationDate &lt;= #{endDate}
        </if>
    </where>
    order by creationDate desc
    limit #{offset}, #{pageSize}
</select>

if+trim

<trim> 用于控制 SQL 片段的前缀和后缀,以及移除多余的字符。

  • prefix:前缀,添加到生成的SQL片段前面的字符串。
  • suffix:后缀,添加到生成的SQL片段后面的字符串。
  • prefixOverrides:对 trim 包含内部的首部进行指定内容的忽略
  • suffixOverrides:对 trim 包含内部的尾部进行指定内容的忽略
xml 复制代码
<trim prefix="where" prefixOverrides="and|or"></trim>

动态生成WHERE子句,确保生成的SQL语句中WHERE关键字后面没有多余的ANDOR关键字。

xml 复制代码
<trim prefix="set" suffixOverrides="," suffix="where id=#{id}">
    <if test="uname != null">uname=#{uname},</if>
    <if test="upwd != null">upwd=#{upwd},</if>
</trim>

动态生成SET子句,并确保生成的SQL语句中SET关键字后面没有多余的逗号,并且在最后加上WHERE子句。

xml 复制代码
<!-- 添加用户 -->
<insert id="save">
    INSERT INTO smbms_user (
    userCode,
    userName,
    <trim suffixOverrides=",">
        <if test="gender != null">gender,</if>
        <if test="birthday != null">birthday,</if>
        <if test="address != null">address,</if>
    </trim>
    )
    VALUES (
    #{userCode},
    #{userName},
    <trim suffixOverrides=",">
        <if test="gender != null">#{gender},</if>
        <if test="birthday != null">#{birthday},</if>
        <if test="address != null">#{address}</if>
    </trim>
    )
</insert>

或者

xml 复制代码
INSERT INTO smbms_user
<trim prefix="(" suffix=")" suffixOverrides=",">
    <if test="userCode != null">userCode,</if>
    <if test="userName != null">userName,</if>
    <if test="gender != null">gender,</if>
    <if test="birthday != null">birthday,</if>
    <if test="address != null">address,</if>
</trim>
VALUES
<trim prefix="(" suffix=")" suffixOverrides=",">
    <if test="userCode != null">#{userCode},</if>
    <if test="userName != null">#{userName},</if>
    <if test="gender != null">#{gender},</if>
    <if test="birthday != null">#{birthday},</if>
    <if test="address != null">#{address}</if>
</trim>

第一段代码适用于某些字段(如 userCodeuserName)总是必须提供的情况,固定字段和动态字段分开处理。

第一段代码适用于所有字段都可以为空的情况,所有字段都动态处理。

foreach

循环遍历集合参数

  • collection:接收的集合参数
  • open /close:以何打开/关闭
  • separator:间隔符号
  • item:单个变量名
java 复制代码
/**
 * 批量删除
 * @param ids id列表
 * @return 受影响行数
 */
int deleteByList(List<Integer> ids);
xml 复制代码
<!-- 删除多个用户 -->
<delete id="deleteByList" >
    DELETE FROM smbms_user WHERE id in
    <foreach collection="list"  open="("  separator=","  close=")"  item="id">
        #{id}
    </foreach>
</delete>

collection 除了传递 list 还可以传递 array、map

java 复制代码
/**
 * 多查询 根据用户ID查询地址
 * @param ids id列表
 * @return 地址列表
 */
List<Address> findAddressArray(Integer[] uids);

List<Address> findAddressMap(Map<String,Object> map);
xml 复制代码
<select id="findAddressArray" resultType="Address">
    SELECT id,contact,addressDesc,postCode FROM smbms_address WHERE userId in
    <foreach collection="array"  open="("  separator=","  close=")"  item="uid">
        #{uid}
    </foreach>
</select>
<select id="findAddressMap" resultType="Address">
    SELECT id,contact,addressDesc,postCode FROM smbms_address WHERE userId in
    <foreach collection="uids"  open="("  separator=","  close=")"  item="uid">
        #{uid}
    </foreach>
    and addressDesc like concat('%', #{addressDesc}, '%')
</select>
java 复制代码
public void findAddressArray(){
    addressDao.findAddressArray(new Integer[]{1,2});
}
public void findAddressMap(){
    Map<String,Object> map = new Map<String,Object>();
    map.put("addrDesc","西城区");
	map.put("uids",Arrays.asList(1,2,3));
    addressDao.findAddressArray(map);
}

choose

xml 复制代码
<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>

sql

使用<sql>标签定义一个可重用的SQL片段。

xml 复制代码
<sql id="query_user_where">
    <where>
        <if test="userName != null and userName != ''">
            and userName like concat('%', #{userName}, '%')
        </if>
        <if test="address != null and address != ''">
            and address like concat('%', #{address}, '%')
        </if>
        <if test="beginDate != null and beginDate != ''">
            and creationDate &gt;= #{beginDate}
        </if>
        <if test="endDate != null and endDate != ''">
            and creationDate &lt;= #{endDate}
        </if>
    </where>
</sql>

在查询中使用<include>标签引入定义的SQL片段。

xml 复制代码
<!-- 分页查询 -->
<select id="findAll" resultType="User">
    select id,userCode,userName,gender,birthday,address,creationDate
    from smbms_user
    <include refid="query_user_where"/>
    order by creationDate desc
    limit #{offset}, #{pageSize}
</select>

<!-- 查询列表总数 -->
<select id="findListCount" resultType="int">
    select count(1) as count
    from smbms_user
    <include refid="query_user_where"/>
</select>
相关推荐
or77iu_N1 小时前
SpringBoot 中的测试jar包knife4j(实现效果非常简单)
java·开发语言·spring boot·后端·mybatis·jar
Mr.kanglong2 小时前
【MySQL】初始MySQL、库与表的操作
数据库·mysql
好记性+烂笔头2 小时前
3 Spark SQL
大数据·sql·spark
GIS小小研究僧2 小时前
PostgreSQL 数据库备份与还原
数据库·postgresql·oracle·postgis
西木Qi3 小时前
数据库备份、主从、集群等配置
数据库
qw9493 小时前
MySQL(高级特性篇) 13 章——事务基础知识
数据库·mysql
MXsoft6183 小时前
基于监控易一体化运维软件的浪潮服务器监控指标详解
运维·数据库
码农幻想梦3 小时前
实验十 数据库完整性实验
数据库·sql·oracle
小安同学iter3 小时前
MySQL数据库(二)
数据库·sql·mysql·oracle
努力成为头发茂密的程序员4 小时前
(0基础版,无需输入代码爬取)新手小白初步学习八爪鱼采集器
数据库·学习·数据分析