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

展望

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

相关推荐
罗超驿17 小时前
6.Java多线程详解:Thread类、线程属性与start()方法深度解析
java·开发语言·面试·java-ee
苦逼的猿宝17 小时前
IT技术交流和分享平台的设计与实现(源码+论文)
java·毕业设计·springboot·计算机毕业设计
摇滚侠18 小时前
IDEA 需要修改的配置 开发工具
java·ide·intellij-idea
2601_9577867718 小时前
企业矩阵运营的“三段论“:管号、产内容、获线索——全链路系统的价值拆解
java·前端·矩阵·多平台管理
Run_Teenage18 小时前
算法模板:输入输出,并查集
java·开发语言·算法
一 乐18 小时前
公交线路查询系统|基于Java+vue公交线路查询系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·公交线路查询系统
AllData公司负责人18 小时前
亲测丝滑,体验跃迁|AllData通过集成开源项目Datart,让数据可视化一目了然
java·大数据·数据库·python·数据可视化·数据视图·datart
未若君雅裁18 小时前
RabbitMQ 高可用机制:普通集群、镜像队列与仲裁队列
java·微服务·rabbitmq·java-rabbitmq
i220818 Faiz Ul18 小时前
相亲网站|相亲网站系统|基于Java+vue相亲网站系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·相亲网站系统
asdfg125896318 小时前
str.charAt(i)和c.charValue()区分(c是Character (对象))
java