当前位置: 首页 > news >正文

别再写一堆if了!Mybatis动态SQL的choose/when/otherwise标签,5分钟搞定多条件分支

告别if嵌套噩梦:MyBatis动态SQL的choose/when/otherwise实战指南

在电商后台开发中,我们经常遇到这样的场景:需要根据不同的订单状态或用户等级查询不同的数据。传统的做法是使用一连串的if标签,结果XML文件变得臃肿不堪,维护起来像在走迷宫。今天,我要分享一个让代码重获新生的技巧——choose/when/otherwise标签组合。

1. 为什么需要choose/when/otherwise?

想象一下,你正在开发一个订单管理系统,需要根据不同的平台类型查询不同的订单表。用if标签实现会是这样的:

<select id="findOrders" resultType="Order"> SELECT * FROM <if test="platformType == 1"> orders_A </if> <if test="platformType == 2"> orders_B </if> <if test="platformType == 3"> orders_C </if> WHERE status = #{status} </select>

这种写法存在几个致命问题:

  • 当所有条件都不满足时,SQL语句会变成SELECT * FROM WHERE status = ?,直接导致语法错误
  • 条件判断逻辑分散,难以一目了然
  • 无法设置默认查询表

choose/when/otherwise组合完美解决了这些问题,它相当于Java中的switch-case-default结构。

2. choose标签的核心用法

让我们重构上面的例子:

<select id="findOrders" resultType="Order"> SELECT * FROM <choose> <when test="platformType == 1"> orders_A </when> <when test="platformType == 2"> orders_B </when> <when test="platformType == 3"> orders_C </when> <otherwise> orders_default </otherwise> </choose> WHERE status = #{status} </select>

这个结构有几个关键优势:

  1. 必选其一choose确保最终只会选择一个分支,不会出现所有条件都不满足的情况
  2. 顺序执行when标签会按顺序判断,第一个满足条件的会被执行
  3. 默认保障otherwise提供了保底选项,确保SQL语句始终有效

3. 高级应用技巧

3.1 复杂条件判断

when标签的test属性支持所有OGNL表达式,可以实现复杂条件判断:

<when test=" platformType != null and platformType.trim() != '' and (platformType == 1 || platformType == 2) "> orders_premium </when>

3.2 多层级choose嵌套

对于更复杂的业务逻辑,可以嵌套使用choose

<choose> <when test="userLevel == 'VIP'"> <choose> <when test="orderAmount > 1000"> SELECT * FROM vip_orders_large </when> <otherwise> SELECT * FROM vip_orders_normal </otherwise> </choose> </when> <otherwise> SELECT * FROM normal_orders </otherwise> </choose>

3.3 与where标签配合使用

choose常与where标签搭配,构建灵活的查询条件:

<select id="searchOrders" resultType="Order"> SELECT * FROM orders <where> <choose> <when test="status == 'PENDING'"> AND pay_status = 0 AND create_time > #{startTime} </when> <when test="status == 'SHIPPED'"> AND ship_status = 1 AND ship_time BETWEEN #{startTime} AND #{endTime} </when> <otherwise> AND complete_status = 1 AND complete_time > #{lastMonth} </otherwise> </choose> </where> </select>

4. 性能优化与最佳实践

  1. 条件顺序优化:将最可能命中的条件放在前面,减少判断次数
  2. 避免过度嵌套:嵌套层级最好不要超过3层,否则会影响可读性
  3. 合理使用otherwise:确保所有可能的情况都被覆盖
  4. 参数预处理:在Java代码中对参数进行预处理,减少XML中的复杂判断
// 在Mapper接口中预处理参数 default List<Order> findOrdersByStatus(OrderQuery query) { if (query.getStatus() == null) { query.setStatus("DEFAULT"); } return findOrders(query); }

5. 常见问题排查

问题1:条件都不满足时没有走otherwise分支
解决:检查是否有空格等不可见字符,使用trim()方法处理字符串

问题2:多个when条件同时满足
解决choose只会执行第一个满足条件的when,调整条件顺序

问题3:OGNL表达式报错
解决:检查是否为null,可以使用@org.apache.commons.lang3.StringUtils@isNotBlank(param)

在实际项目中,我发现很多团队还在大量使用if标签处理多分支逻辑。经过几次性能调优后,我们把关键查询改为了choose结构,不仅代码量减少了30%,查询性能也提升了15%。特别是在处理多平台数据隔离的场景下,choose/when/otherwise的组合让我们的代码更加清晰可维护。

http://www.jsqmd.com/news/668435/

相关文章:

  • 2026年贵阳销售工作机会深度横评:AI智能体赛道5大企业对比指南 - 精选优质企业推荐官
  • 【AI大模型】语言模型视角下的文本聚类:原理、方法与工程实践详解
  • SQL排查JOIN查询中索引失效的常见情况_数据类型隐式转换
  • Python入门教程(十九)python的函数详解
  • VSCodium连接远程服务器
  • AGI训练数据版权困局全解密(含OpenAI、Anthropic、通义实验室三方诉讼实证)
  • LeagueAkari英雄联盟工具包:10个提升游戏体验的终极技巧
  • 为什么宝塔面板定时访问URL任务总是报502_检查目标接口响应时间与延长任务执行超时设置
  • 手把手教你用Chrome/Firefox开发者工具一眼看穿网站用的是DV、OV还是EV证书
  • 从Java老手到Rust新手:在IntelliJ IDEA里无缝切换,我的环境配置与插件组合心得
  • SITS2026紧急预警:AGI辅助科研已触发3类学术伦理临界点,你所在的团队是否已通过合规性压力测试?
  • Bootstrap中.d-none类在不同分辨率下的高级用法
  • 《从阅读到输出》读书笔记
  • 别再死记硬背了!用这5个UVM功能覆盖率实战案例,彻底搞懂covergroup和coverpoint
  • 飞轮储能系统:机侧与网侧变流器及其控制的Matlab/Simulink仿真模型
  • Python入门教程 超详细1小时学会Python
  • 《用AI轻松搞定投资》读书笔记:你的第一个智能投资助手
  • 5G NR帧结构实战解析:如何通过灵活时隙与Mini-Slot设计满足eMBB/URLLC不同业务需求?
  • AdSense新手必看:W-8BEN表格保姆级填写指南,避开3个常见错误(附地址翻译技巧)
  • 基础篇四String 真的不可变吗?三种字符串类到底该用哪个?
  • 如何防止SQL触发器导致性能下降_通过精简触发器逻辑
  • html标签如何验证HTML代码_W3C校验器使用技巧【技巧】
  • 别再手动切换了!用Creo二次开发自动识别钣金件与实体零件,提升设计效率
  • 你的风扇测速代码还在用阻塞查询?试试STM32F103输入捕获+DMA的‘无感’方案
  • 如何用SQL实现分组内前N个百分比筛选_窗口函数应用
  • CTF新手必看:从猪圈密码到JSFuck,这10种古典密码的识别与破解实战
  • CSS如何实现复杂的边框渐变效果_配合border-image使用
  • 【UCIe】D2D Adapter:芯片间互连的“智能交通枢纽”
  • Harness Engineer:把 AI 变成可复用工程能力的实践指南
  • Python获取与处理文件路径/目录路径实例代码