MyBatis 中 where1=1 一些替换方式

题记

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

起因

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

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

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

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

替换方式

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

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

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

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

看实例:

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 = ?
  • 当传 username 和 age 时,此时执行的Sql语句为:SELECT * FROM user WHERE username = ? AND age = ?

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

<trim> 可更灵活地处理 SQL 片段,通过设置 prefix 和 prefixOverrides 属性模拟 <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 ":移除条件前多余的 AND 或 OR。

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> 多条件动态组合 自动处理 WHERE 和 AND 需MyBatis 框架支持
<trim> 复杂 SQL 片段处理 灵活度比较高 配置稍繁琐
<choose> 多条件互斥选择 逻辑清晰 无明确条件时仍需 1=1
Java代码判断控制 条件逻辑复杂 完全可控 增加Service层代码复杂度

总结

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

展望

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

相关推荐
Json____9 小时前
家居装修 AI 智能咨询助手:让装修咨询从“大海捞针“变成“一问即答“
java·后端·vue3·it学习·wwwoop.com
vipxieliang9 小时前
ValidX 在微服务架构中的验证策略
java·spring boot
用户094248568039 小时前
第18章:ConcurrentHashMap与并发容器实战
java·jvm
小羊没烦恼!9 小时前
在Scrum中实施敏捷建模
java·开发语言·windows·算法·c#
❀͜͡傀儡师9 小时前
20 年沉淀,CAS 8.0 重新定义企业级 SSO:适配 JDK 25 与 Spring Boot 4.1
java·开发语言·spring boot
牧瀬クリスだ10 小时前
Spring统一功能处理
java·spring boot·spring·状态模式
SL_staff10 小时前
从钉钉日报到动态数据看板:面向业务侧的低代码BI实践路径
java·数据分析·数据可视化
TDengine (老段)10 小时前
TDengine TSDB 实战排障四(升级与兼容)
android·java·大数据·数据库·物联网·时序数据库·tdengine
nhdh10 小时前
SpringAI与SpringAIAlibaba:标准与生态的完美互补
java·人工智能·spring
Apifox10 小时前
Apifox 9 月更新|CLI 能力升级、GitLab 私有化部署接入与产品体验优化
前端·后端·测试