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

news/2025/9/20 10:20:19/文章来源:https://www.cnblogs.com/sly-345/p/19102052
//错误
<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.mzph.cn/news/908254.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入解析:人工智能学习:什么是LSTM模型

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

直播软件搭建,如何实现伪分布式平台部署? - 云豹科技

直播软件搭建,如何实现伪分布式平台部署?大数据平台搭建合集–伪分布式平台部署0.更改主机名并配置hosts映射# 更改主机名 hostnamectl set-hostname master # 配置hosts映射 vi /etc/hosts [填当前机器真是ip] mast…

初步研究vivio的互传的备份数据格式

初步研究vivio的互传的备份数据格式一般来说最大的那个文件是apk, 下面是我的分析,先进入db文件夹,找到000003.log 形如下图的就是apk文件。重命名加上.apk就能单独提取,文件名是hash函数计算过的。 形如下图的就是…

完整教程:C#.NetCore NPOI 导出excel 单元格内容换行

完整教程:C#.NetCore NPOI 导出excel 单元格内容换行pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&qu…

resultMap和resultType

resultMap 和 resultType好的,这是一个非常核心的MyBatis面试题和日常开发中的关键知识点。resultMap 和 resultType 都用于指定SQL查询结果的返回类型,但它们的用法和能力有本质区别。 下面我用一个清晰的对比和示例…

RabbitMQ 幂等性, 顺序性 和 消息积压 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

直播软件怎么开发,自适应两栏布局方式 - 云豹科技

直播软件怎么开发,自适应两栏布局方式html结构<body><div class="wrapper"><div class="left"></div><div class="right"></div></div><…

基于SpringBoot的足球论坛系统+论文示例参考 - 指南

基于SpringBoot的足球论坛系统+论文示例参考 - 指南2025-09-20 10:01 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; disp…

resultMap和自定义映射结果形式(ResultMapManage)以及ResultMap Vs ResultType

resultMap和自定义映射结果形式(ResultMapManage)以及ResultMap Vs ResultType<resultMap id="ResultMapManage" type="com.javapandeng.po.Manage"><result property="id" …

嵌入式设备不能正常上网问题

问题描述 设置静态IP和默认网关,设备无法上网。尝试ping baidu.com 也无法ping通 解决方案 1.默认网关IP设置错了 默认网关IP = 路由器IP 当设备在当前的链路中找不到baidu的IP时,会把IP传输到路由器,路由器通过查找…

2、论文固定模板(背景过度结尾)

1、论文字数分配2、以上仅供参考,如有疑问,留言联系

go: 图片文件上传

一,代码 go //上传页面 func (ic *MediaController) Upload(c *gin.Context) {c.HTML(200, "upload.html", nil) }//接收上传,多张图片 func (ic *MediaController) Uploaded(c *gin.Context) {//得到form…

go: 生成缩略图

一,安装第三方库 $ go get -u github.com/disintegration/imaging go: downloading golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 go: downloading golang.org/x/image v0.31.0 go: added github.com/disi…

git: 报错: fatal: 协议错误:错误的行长度字符串:This 或 fatal: protocol error: bad line length character: This

一,报错信息: fatal: 协议错误:错误的行长度字符串:This 或 fatal: protocol error: bad line length character: This 二,出现的原因: 我修改了git项目的remote地址,是因为gitolite服务换了一台服务器,报错的原…

jquery: Justified gallery

一,官网 官网: https://miromannino.github.io/Justified-Gallery/ github: https://github.com/miromannino/Justified-Gallery二,使用 引入: <link rel="stylesheet" href="/static/justified/j…

安装crmeb

一,官网: https://www.crmeb.com/xiazai 代码站: https://gitee.com/ZhongBangKeJi/CRMEB 安装参考文档地址: https://doc.crmeb.com/single_open/open_v54/20389 二,下载 用git命令下载 $ git clone https://gitee.…

gin: 打包模板文件、静态文件到二进制文件中

一,默认html模板不会打包到二进制文件中 如果二进制文件的当前目录下不包含html模板文件路径,会报错如下 $ ./mediabank [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middlew…

gin: 判断是否ajax请求

一,代码 controller: //得到用户信息 func (ic *MediaController) User(c *gin.Context) {if c.Request.Header.Get("X-Requested-With") == "XMLHttpRequest" {c.JSON(http.StatusOK, gin.H{&qu…

gin: 静态文件

一,下载jquery 官网: https://jquery.com/ 从命令行下载: $ wget https://code.jquery.com/jquery-3.7.1.min.js 二,代码: 目录结构routes package routesimport ("github.com/gin-gonic/gin""mediab…

详细介绍:【论文精读】基于YOLOv3算法的高速公路火灾检测

详细介绍:【论文精读】基于YOLOv3算法的高速公路火灾检测pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consola…