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 的简洁性和规范性。

展望

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

相关推荐
cc蒲公英6 分钟前
uniapp x swiper/image组件mode=“aspectFit“ 图片有的闪现后黑屏
java·前端·uni-app
刘大辉在路上7 分钟前
IntelliJ IDEA开发编辑器摸鱼看股票数据
java·编辑器·intellij-idea
Jacob023412 分钟前
Node.js 性能瓶颈与 Rust + WebAssembly 实战探索
后端·rust·node.js
王中阳Go21 分钟前
分库分表之后如何使用?面试可以参考这些话术
后端·面试
知其然亦知其所以然26 分钟前
ChatGPT太贵?教你用Spring AI在本地白嫖聊天模型!
后端·spring·ai编程
我来整一篇1 小时前
[mysql] 深分页优化
java·数据库·mysql
Sadsvit1 小时前
Linux 服务器性能监控、分析与优化全指南
java·linux·服务器
hqxstudying1 小时前
Java开发时出现的问题---语言特性与基础机制陷阱
java·jvm·python
kinlon.liu1 小时前
内网穿透 FRP 配置指南
后端·frp·内网穿透
kfyty7251 小时前
loveqq-mvc 再进化,又一款分布式网关框架可用
java·后端