优化MyBatis查询条件:从Boolean类型判断到<choose>标签的进化

需求背景

作为一名Java CRUD Coder,日常开发中会遇到类似的需求:通过下拉列表选择"是"或"否"来对数据库中的数据进行筛选。如果此时前端的传参是boolean类型的truefalse,后端Mapper层的代码可能会遇到需要构造类似if (param.existFlag) and table.id not in (xxxx1,xxxx2)这样的条件查询,如果你们的ORM框架使用的是MyBatis/MyBatis Plus,请看下文内容。

MyBatis参数映射

错误写法

Java中在写判断条件时,可以使用:

java 复制代码
if(existFlag) {
    //do something
}

在MyBatis的XML中,不可以使用类似的写法:

xml 复制代码
<if test="param.existFlag">
  AND id = 1
</if>

正确写法

xml 复制代码
<if test="param.existFlag != null and param.existFlag == true">
  AND id = 1
</if>

注意事项及优化

缺陷

当我们需要在SQL中需要根据true、false、null执行不同的逻辑时,尽管MyBatis支持上述写法,但这种写法难免不太容易理解。

xml 复制代码
<select id="selectUsersByFlag" resultType="User">
    SELECT * FROM users
    <where>
        <if test="existFlag != null and existFlag == true">
            AND id = 1
        </if>
        <if test="existFlag != null and existFlag == false">
            AND id = 2
        </if>
        <if test="existFlag == null">
            -- 处理字段为null的情况,此处略
        </if>
    </where>
</select>

既然true、false都需要判断,那么这种写法就相当于:

java 复制代码
if (existFlag) {
    // do something 1
} else if (!existFalg){
    //do something 2
} else {
    //do something 3
}

当if条件变得更多时,代码的逻辑结构显然会变得更臃肿,不易理解。那么我们需要再优化一下。

优化

在Java中,当判断条件变多时,可以使用switch语句、策略模式等方案优化,那么在MyBatis中可以使用<choose>进行优化。

MyBatis中的<choose>标签用于在多个条件中选择第一个满足条件的子句。类似于Java中的switch语句,<choose>标签可以根据不同的条件选择执行不同的SQL子句,提高SQL语句的灵活性和可读性。

以上代码可以优化为:

xml 复制代码
<select id="selectUsersByFlag" resultType="User">
  SELECT * FROM users
  <where>
    <choose>
      <when test="existFlag != null and existFlag == true">
        AND id = 1
      </when>
      <when test="existFlag != null and existFlag == false">
        AND id = 2
      </when>
      <otherwise>
        and id = 3
      </otherwise>
    </choose>
  </where>
</select>

同样,也可以使用casewhen优化:

xml 复制代码
SELECT *
FROM users
WHERE
CASE
WHEN existFlag = true THEN id = 1
WHEN existFlag = false THEN id = 2
ELSE
END

写到最后的一点想法

作为一名程序员,我们的代码首先要保证功能可用,在功能可用的前提下,要保证代码质量可读性、安全、性能等。吾日三省吾身,多思考一下代码如何能写的更好,这要求我们需要不断探索代码的最佳实践。

保持持续学习的态度,每天优化一点点,一点点改进,从而写出更加优雅、高效和安全的代码。

后续内容文章持续更新中...

近期发布。


关于我

👋🏻你好,我是Debug.c。微信公众号:种棵代码技术树 的维护者,一个跨专业自学Java,对技术保持热爱的bug猿,同样也是在某二线城市打拼四年余的Java Coder。

🏆在掘金、CSDN、公众号我将分享我最近学习的内容、踩过的坑以及自己对技术的理解。

📞如果您对我感兴趣,请联系我。

若有收获,就点个赞吧,喜欢原图请私信我。

相关推荐
晚染烟29 分钟前
每日八股day31
mybatis
why技术1 小时前
eli5,我觉得这个全网在吹的技能,使用体验真的很一般啊。
前端·人工智能·后端
学习星球1 小时前
Qwik 框架入门实战:从开源项目 Qwik City 开始,用可恢复性替代水合
后端·前端框架·开源·c5全栈
阮胜昌2 小时前
MySQL 中的动态数据脱敏:无需更改应用程序即可保护敏感数据
android·mysql·adb
IT_陈寒3 小时前
被Java的final坑惨了,这些细节你可能也忽略了
前端·人工智能·后端
Zadig3 小时前
企业 Agent 总烂在 Demo 里?Zadig 工作流 AI 任务给了一条路
后端·devops
Zadig3 小时前
告别"人肉扛雷":Zadig 用 AI 接管发布前最脏最累的 15 分钟
后端·aiops
Nturmoils4 小时前
向量数据库不该成为新孤岛:KingbaseES 多模融合架构如何减少数据搬运
后端
一座古城4 小时前
Claude Code 架构源码解析:AI 应用开发的范式跃迁
前端·后端
Nturmoils4 小时前
用蓝耘元生代做 GitHub 热榜解读:Dify Chatflow 接入和真实项目分析
后端