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

mybatis 单值或多值传参存在风险举例分析

代码如下,存在风险

 <if test="budgetYear != null and budgetYear != ''">AND budget_year = #{budgetYear}</if><if test="budgetYears != null">AND budget_year IN<foreach open="(" close=")" collection="budgetYears" index="no" item="budgetYear" separator=",">#{budgetYear, jdbcType=VARCHAR}</foreach></if>

分析如下

这段 MyBatis 动态 SQL 代码可能存在以下几个潜在的 Bug 或优化点:


1. 数组/集合空值判断不严谨(严重问题)

问题点
<if test="budgetYears != null"> 只检查了是否为 null,没有检查空数组/空集合
风险
如果传入空数组 budgetYears = [],会生成错误 SQL:budget_year IN ()
修复建议

xml

复制

<if test="budgetYears != null and budgetYears.length > 0">
<!-- 如果是集合则用 !budgetYears.isEmpty() -->

运行 HTML


2. 参数名冲突(逻辑问题)

问题点
item="budgetYear" 与外部参数 budgetYear 同名
风险
在 <foreach> 内部使用时可能产生歧义(取决于 MyBatis 版本)
修复建议

xml

复制

<foreach ... item="yearItem">  <!-- 改为不同名 -->#{yearItem, jdbcType=VARCHAR}
</foreach>

运行 HTML


3. 条件互斥缺失(业务逻辑问题)

问题点
budgetYear 和 budgetYears 两个条件可能同时生效
风险
如果同时传入 budgetYear=2023 和 budgetYears=[2024],会导致矛盾条件:

sql

复制

WHERE budget_year = 2023 AND budget_year IN (2024)  -- 永远无结果

修复建议
改用 <choose> 结构确保互斥:

xml

复制

<choose><when test="budgetYear != null and budgetYear != ''">AND budget_year = #{budgetYear}</when><when test="budgetYears != null and budgetYears.length > 0">AND budget_year IN (...)</when>
</choose>

运行 HTML


4. 缺少类型安全校验(潜在问题)

问题点
没有验证 budgetYears 数组元素的有效性
风险
如果数组包含 null 值(如 ["2023", null]),可能引发异常
修复建议

xml

复制

<foreach ...><!-- 添加 javaType 确保类型安全 -->#{yearItem, jdbcType=VARCHAR, javaType=string}
</foreach>

运行 HTML


5. 索引参数未使用(冗余代码)

问题点
定义了 index="no" 但未实际使用
修复建议
直接移除(除非需要索引值):

xml

复制

<foreach ... item="yearItem" separator=",">

运行 HTML


最终修正版本

xml

复制

<choose><!-- 单值优先 --><when test="budgetYear != null and budgetYear != ''">AND budget_year = #{budgetYear}</when><!-- 多值备选 --><when test="budgetYears != null and budgetYears.length > 0">AND budget_year IN<foreach collection="budgetYears" item="yearItem" open="(" close=")" separator=",">#{yearItem, jdbcType=VARCHAR, javaType=string}</foreach></when>
</choose>

运行 HTML


其他注意事项

  1. SQL 注入风险
    虽然 MyBatis 预处理语句能防御大部分注入,但确保 budgetYear 不直接拼接 SQL

  2. 性能影响
    IN 子句随着数组变大可能影响性能(建议超过 1000 值时改用临时表)

  3. 兼容性
    如果 budgetYears 可能是 Collection 而非数组,需要改用 !isEmpty() 判断

相关文章:

  • 《似锦》:画饼之—你画给我我画给你
  • SVM-RF回归预测matlab代码
  • C++lambda表达式及其在Qt中的使用
  • 前端请求传参与后端匹配的接收方式Content-Type类型
  • 自问自答模式(Operation是什么)
  • 血脂中胆固醇高到转成正常的分析(计算机语言)
  • 【C++】12.list接口介绍
  • 【android bluetooth 框架分析 02】【Module详解 4】【Btaa 模块介绍】
  • vue3、原生html交互传值
  • 网安融合:打造网络+安全一体化的超预期体验
  • 那些能够直接编译到 WebAssembly 的 Rust Crates
  • Sentinel源码—4.FlowSlot实现流控的原理二
  • 微机控制电液伺服汽车减震器动态试验系统
  • 【4.1.-4.20学习周报】
  • Java SpringBoot的自定义配置
  • 使用 XWPFDocument 生成表格时固定列宽度
  • JS实现RSA加密
  • 高共模干扰场景下电压检测技术革新——光电隔离方案解析
  • docker占用磁盘100%
  • 富勒 (Fuller) 投影
  • 赵厚均评《唐诗与唐代园林景观的审美建构研究》|林泉恣探历,风景暂徘徊
  • AI把野史当信史?警惕公共认知的滑坡
  • 即日起,“应急使命·2025”演习公开征集新质救援能力
  • 李乐成任工业和信息化部部长
  • 《求是》杂志发表习近平总书记重要文章《激励新时代青年在中国式现代化建设中挺膺担当》
  • 街区党支部书记们亮出治理实招,解锁“善治街区二十法”