MyBatis 中 where1=1 一些替换方式

题记

生命中的风景千变万化,但我一直在路上。
风雨兼程,不是为了抵达终点,而是为了沿途的风景。

起因

今天闲来无事,翻翻看看之前的项目。

在看到一个项目的时候,项目框架用的是SpringMvc+Spring+Mybatis。项目里面注释时间写的是2018年,时间长了,里面有好多语法现在看起来好麻烦的样子呀!

说有它就有,这不就有一个吗?在Mybatis配置的xml中,有好多where 1=1 拼接Sql的方式,看的人头都大了。想着改一下吧,又一想,代码已经时间长了,如果出现问题找谁,就先不管了。

话是这样说,但在实际工作中,还是会有方法可以代替的,下面我们一起来看看吧!

替换方式

在 MyBatis 中,WHERE 1=1 通常用来在多条件查询情况下下进行SQL 拼接,其目的就是避免在没有条件时出现语法错误。

但这种写法不够优雅,可通过以下方式进行替代:

1. 使用 <where> 标签(推荐)

MyBatis 的 <where> 标签会自动处理 SQL 的 WHERE 语句,移除多余的 ANDOR 关键字。

看实例:

xml 复制代码
<select id="selectUsers" resultType="User"> 
    SELECT * FROM user 
    <where> 
        <if test="username != null and username != ''"> 
            AND username = #{username} 
        </if> 
        <if test="age != null"> 
            AND age = #{age}
        </if> 
    </where> 
</select>

效果说明:

  • 当无参数时,此时执行的Sql语句为:SELECT * FROM user
  • 当仅传 username 时,此时执行的Sql语句为:SELECT * FROM user WHERE username = ?
  • 当传 usernameage 时,此时执行的Sql语句为:SELECT * FROM user WHERE username = ? AND age = ?

2. 使用 <trim> 标签自定义

<trim> 可更灵活地处理 SQL 片段,通过设置 prefixprefixOverrides 属性模拟 <where> 的功能。

看实例:

xml 复制代码
<select id="selectUsers" resultType="User">
  SELECT * FROM user
  <trim prefix="WHERE" prefixOverrides="AND |OR ">
    <if test="username != null and username != ''">
      AND username = #{username}
    </if>
    <if test="age != null">
      AND age = #{age}
    </if>
  </trim>
</select>

说明:

  • prefix="WHERE":在条件前添加 WHERE 关键字。
  • prefixOverrides="AND |OR ":移除条件前多余的 ANDOR

3. 使用 <choose><when><otherwise>

类似Java在进行判断中常用的 switch-case语句,此方式适用于多条件互斥的场景。

看实例:

xml 复制代码
<select id="selectUsers" resultType="User">
  SELECT * FROM user
  <where>
    <choose>
      <when test="username != null and username != ''">
        username = #{username}
      </when>
      <when test="age != null">
        age = #{age}
      </when>
      <otherwise>
        1=1  <!-- 仅在无任何条件时使用 -->
      </otherwise>
    </choose>
  </where>
</select>

4. Java代码判断控制

在 Service 层根据条件动态选择不同的 SQL 语句。

看实例:

java 复制代码
public List<User> getUsers(String username, Integer age) {
    if (username != null && !username.isEmpty()) {
        return userMapper.selectByUsername(username);
    } else if (age != null) {
        return userMapper.selectByAge(age);
    } else {
        return userMapper.selectAll();
    }
}

具体方式对比与选择

方式 适用场景 优点 缺点
<where> 多条件动态组合 自动处理 WHEREAND 需MyBatis 框架支持
<trim> 复杂 SQL 片段处理 灵活度比较高 配置稍繁琐
<choose> 多条件互斥选择 逻辑清晰 无明确条件时仍需 1=1
Java代码判断控制 条件逻辑复杂 完全可控 增加Service层代码复杂度

总结

推荐优先使用 <where> 标签,它能自动处理 SQL 语法,避免冗余代码。只有在需要更精细控制时,才考虑 <trim> 或其他方式。尽量避免在 XML 中使用 WHERE 1=1,保持 SQL 的简洁性和规范性。

展望

世间万物皆美好, 终有归途暖心潮。
在纷繁的世界里,保持内心的宁静与坚定,让每一步都走向完美的结局。

相关推荐
Grey Zeng1 小时前
Java SE 25新增特性
java·jdk·jdk新特性·jdk25
追逐时光者2 小时前
精选 4 款基于 .NET 开源、功能强大的 Windows 系统优化工具
后端·.net
雨白2 小时前
Java 线程通信基础:interrupt、wait 和 notifyAll 详解
android·java
TF男孩2 小时前
ARQ:一款低成本的消息队列,实现每秒万级吞吐
后端·python·消息队列
AAA修煤气灶刘哥3 小时前
别让Redis「歪脖子」!一次搞定数据倾斜与请求倾斜的捉妖记
redis·分布式·后端
AAA修煤气灶刘哥4 小时前
后端人速藏!数据库PD建模避坑指南
数据库·后端·mysql
你的人类朋友4 小时前
什么是API签名?
前端·后端·安全
昵称为空C6 小时前
SpringBoot3 http接口调用新方式RestClient + @HttpExchange像使用Feign一样调用
spring boot·后端
架构师沉默6 小时前
设计多租户 SaaS 系统,如何做到数据隔离 & 资源配额?
java·后端·架构
RoyLin7 小时前
TypeScript设计模式:适配器模式
前端·后端·node.js