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

Mapper.xml与数据库进行映射的sql语言注意事项

//错误
<update id="updateBatch" parameterType="java.util.List"><foreach collection="list" item="item" index="index" separator=";">update manage<set><if test="item.userName != null">userName=#{userName},</if><if test="item.passWord != null">passWord=#{passWord},</if><if test="item.realName != null">realName=#{realName}</if></set>where 1=1<if test="item.id!=null">and id=#{item.id}</if></foreach></update>//正确
<update id="updateBatch" parameterType="java.util.List"><foreach collection="list" item="item" index="index" separator=";">update manage<set><if test="item.userName != null">userName = #{item.userName},</if><if test="item.passWord != null">passWord = #{item.passWord},</if><if test="item.realName != null">realName = #{item.realName}</if></set>where 1=1<if test="item.id != null">and id = #{item.id}</if></foreach></update>

核心结论

这些空格大部分是【必要的】,它们直接影响到最终生成的SQL语句的正确性和可读性。 第二段代码在正确性上更优,主要是因为它修正了第一段代码中一个严重的错误


一、逐行对比分析

让我们把两段代码的关键不同点拆解出来:

1. 赋值语句右边的空格(关键错误修正)

  • 第一段代码(错误)

    xml
    userName=#{userName},
    • 问题: #{userName} 前面没有空格。这会导致生成的SQL语句变成 userName=John,,这是一个严重的语法错误。SQL要求赋值操作符两边必须有空格(虽然不是所有数据库都强制要求,但这是标准SQL约定,没有空格非常容易出错)。

  • 第二段代码(正确)

    xml
    userName = #{item.userName},
    • 修正: = 两边都有空格,生成的SQL是 userName = 'John',,这是完全符合SQL语法的标准写法。

2. 参数引用的完整性(关键错误修正)

  • 第一段代码(错误)

    xml
    #{userName}
    • 问题: 它缺少了 item. 前缀。在 MyBatis 的 <foreach> 循环中,每个元素用 item="item" 指定了别名。要访问当前遍历对象的属性,必须使用 item.属性名。这里写 #{userName},MyBatis 会去查找一个叫 userName 的顶级参数,而不是你传入的List中某个对象的属性。这会导致参数绑定失败,值变为 null

  • 第二段代码(正确)

    xml
    #{item.userName}
    • 修正: 正确地引用了当前循环对象 item 的 userName 属性。

3. WHERE 和 AND 前的空格(必要且重要)

  • 第一段代码(有风险)

    xml
    where 1=1
    <if...>and id=#{item.id}</if>
    • 分析: where 1=1 和后面的 and id... 拼接时,会生成 where 1=1and id=1虽然 1=1and 在大多数数据库中被解析为 1=1 and(因为and是关键字),但这种依赖数据库自动识别的做法是有风险的,非常不规范

  • 第二段代码(最佳实践)

    xml
    where 1=1
    <if...> and id = #{item.id}</if>
    • 修正: 在 and 前面显式地加上了一个空格。这样就能确保生成标准的 where 1=1 and id = 1。这是非常良好且必要的习惯

4. 其他空格(主要为了可读性)

像 item.id != null 等表达式中的空格,以及标签内的一些换行和缩进,主要是为了让XML代码本身更清晰、更易读,对最终生成的SQL没有影响。MyBatis在解析动态SQL标签(<if><set>等)时,会智能地处理掉多余的空白字符,只保留SQL语句本身必要的空格。


二、最终生成的SQL对比

假设我们传入的List包含一个对象:{id: 1, userName: "Admin"}

  • 第一段错误代码生成的SQL

    sql
    update manage set userName=, passWord=?, realName=? where 1=1and id=?;

    这是一条完全错误的SQL! 原因:

    1. userName= 后面没有空格,语法怪异。

    2. #{userName} 因引用错误导致值为 null,所以 userName= 后面直接是逗号,语法错误。

    3. where 1=1and id=? 缺少空格,不规范。

  • 第二段正确代码生成的SQL

    sql
    update manage set userName = 'Admin', where 1=1 and id = 1;

    这是一条语法正确、清晰明了的SQL。(注意:即使多了一个逗号,<set> 标签也会负责去掉它)。

三、总结

 
 
差异点 第一段代码 第二段代码 重要性
赋值空格 (=) userName=#{...} userName = #{...} 【关键】:缺少空格会导致SQL语法错误或不规范。
参数引用 #{userName} #{item.userName} 【致命】:缺少 item. 会导致参数绑定失败,值为null。
条件空格 (and) and id=#{...} and id = #{...} 【重要】:显式的空格是良好实践,保证SQL100%正确。
代码格式 空格较少,紧凑 空格较多,清晰 【一般】:影响开发者阅读代码的体验,不影响SQL生成。

结论:第二段代码不仅仅是“多了些空格”,而是修正了第一段代码中存在的两个严重错误(参数引用和SQL语法),是正确、可靠且符合规范的写法。 在编写MyBatis动态SQL时,保证SQL语句本身格式的正确性至关重要。

 

http://www.hskmm.com/?act=detail&tid=10440

相关文章:

  • 直播软件搭建,如何实现伪分布式平台部署? - 云豹科技
  • 初步研究vivio的互传的备份数据格式
  • 完整教程:C#.NetCore NPOI 导出excel 单元格内容换行
  • resultMap和resultType
  • 直播软件怎么开发,自适应两栏布局方式 - 云豹科技
  • resultMap和自定义映射结果形式(ResultMapManage)以及ResultMap Vs ResultType
  • 嵌入式设备不能正常上网问题
  • 2、论文固定模板(背景过度结尾)
  • go: 图片文件上传
  • go: 生成缩略图
  • git: 报错: fatal: 协议错误:错误的行长度字符串:This 或 fatal: protocol error: bad line length character: This
  • jquery: Justified gallery
  • 安装crmeb
  • gin: 用zap记录访问日志
  • gin: 打包模板文件、静态文件到二进制文件中
  • gin: 判断是否ajax请求
  • gin: 静态文件
  • 详细介绍:【论文精读】基于YOLOv3算法的高速公路火灾检测
  • MacOS 下fuzz学习踩坑点
  • An Empirical Study on Commit Message Generation using LLMs via In-Context Learning 论文笔记
  • 实用指南:人工智能学习:Transformer结构中的编码器层(Encoder Layer)
  • vcpkg 安装依赖
  • Java03课前问题列表
  • JavaScript错误处理完全指南:从基础到自定义错误实战
  • 1、论文准备
  • PION 游击
  • Web3 开发者修炼全图谱:从 Web2 走向 Web3 的实用的系统性学习指南
  • 实用指南:医院高值耗材智能化管理路径分析(下)
  • Flutter应用自动更新系统:生产环境的挑战与解决方案
  • .NET Core中使用SignalR