14. /#{} 和 /${} 的区别是什么?

devtools/2024/10/18 16:55:28/

在MyBatis中,#{}${}是两种常见的占位符,它们的作用和使用场景有所不同。理解它们的区别对于正确使用MyBatis非常重要。

1. #{} 和 ${} 的基本区别

#{}:SQL参数占位符

  • 作用#{}用于将传入的参数安全地绑定到SQL语句中,它会自动使用PreparedStatement?占位符机制,并且MyBatis会对传入的参数进行预处理(例如防止SQL注入)。

  • 参数替换:在生成SQL语句时,#{}会被替换为一个?,然后由JDBC驱动程序将参数值绑定到这个?占位符上。

  • 使用场景:通常用于传递用户输入的参数,如查询条件、插入或更新的数据等。

    示例

    java"><select id="findUserById" resultType="User">SELECT * FROM users WHERE id = #{id}
    </select>
    • 如果传入的id为1,MyBatis生成的SQL类似于:SELECT * FROM users WHERE id = ?,然后通过PreparedStatement?替换为1。

${}:SQL文本占位符

  • 作用${}用于直接将传入的参数值替换到SQL语句中,它不会进行预处理,因此直接将参数值插入到SQL语句中。这意味着${}会将参数视为SQL的一部分,可能会导致SQL注入风险。

  • 参数替换:在生成SQL语句时,${}会直接将传入的值替换到SQL语句中,而不会使用?占位符。

  • 使用场景:通常用于动态生成SQL片段,比如排序字段名、表名、列名等不直接来自用户输入的参数。

    示例

    java"><select id="findUserByColumn" resultType="User">SELECT * FROM users WHERE ${columnName} = #{value}
    </select>
    • 如果传入的columnNameusernamevalueJohn,MyBatis生成的SQL类似于:SELECT * FROM users WHERE username = ?,然后通过PreparedStatement?替换为John

2. 安全性和使用建议

  • SQL注入防护:由于#{}会使用PreparedStatement的参数绑定机制,因此可以有效防止SQL注入攻击。而${}直接将参数值拼接到SQL中,可能导致SQL注入,因此应慎重使用。

  • 动态SQL生成${}更适合用于生成动态的SQL片段,比如动态表名、列名等。但要确保传入的值是可信任的,或者通过其他手段确保安全。

3. 具体示例

使用 #{} 的示例

java"><select id="findUserById" resultType="User">SELECT * FROM users WHERE id = #{id}
</select>
  • 传入id为1,生成SQL为:

    java">SELECT * FROM users WHERE id = ?

    然后将参数1安全地绑定到?上。

使用 ${} 的示例

java"><select id="findUserByColumn" resultType="User">SELECT * FROM users WHERE ${columnName} = #{value}
</select>
  • 传入columnNameusernamevalueJohn,生成SQL为:

    java">SELECT * FROM users WHERE username = ?

    然后将参数John绑定到?上。

SQL注入风险示例

java"><select id="findUserByColumn" resultType="User">SELECT * FROM users WHERE ${columnName} = #{value}
</select>
  • 如果传入的columnNameusername OR '1'='1',生成的SQL可能是:

    java">SELECT * FROM users WHERE username OR '1'='1' = ?

    这样就可能导致SQL注入问题。

总结

  • #{}:安全地传递参数,防止SQL注入,常用于传递用户输入的参数。

  • ${}:直接将参数值插入到SQL中,适用于动态生成SQL片段(如表名、列名),但存在SQL注入风险,应谨慎使用。

在实际开发中,建议尽量使用#{}来传递参数,以确保SQL安全性,而对于使用${}的场景,需要确保传入的参数是安全且经过验证的。


http://www.ppmy.cn/devtools/109986.html

相关文章

调度器怎么自己写?调度器在实现时需要注意哪些细节?请写一个jvm的调度器?如何在这个调度器中添加多个任务?

如果你想自己编写一个调度器&#xff0c;可以按照以下步骤进行&#xff1a; 一、确定需求和目标 明确调度器的应用场景&#xff0c;例如任务调度、资源分配、进程管理等。 确定调度的对象&#xff0c;比如任务、作业、进程等。 定义调度的目标&#xff0c;如最小化完成时间、最…

锐捷交换机常用命令

文章目录 1. 基本操作命令2. 接口配置3. VLAN配置4. 链路聚合5. 生成树协议6. 端口安全7. 常用查看命令8. 系统管理9. 配置端口镜像10. 配置生成树协议 1. 基本操作命令 进入特权模式&#xff1a;enable 进入全局配置模式&#xff1a;configure terminal 保存配置&#xff1a;…

Unreal Engine——AI生成高精度的虚拟人物和环境(虚拟世界构建、电影场景生成)(一)

一、Unreal Engine 介绍 Unreal Engine&#xff08;虚幻引擎&#xff09;是由Epic Games开发的强大3D游戏开发引擎&#xff0c;自1998年首次发布以来&#xff0c;已经历了多个版本的迭代。虚幻引擎主要用于制作高品质的3D游戏&#xff0c;但也广泛用于电影、建筑、仿真等其他领…

Hydra爆破与简单使用 ssh rdp ftp

Hydra介绍&#xff1a; 一款非常流行的网络密码破解工具&#xff0c;用于执行暴力破解或字典攻击。它支持多种协议和服务&#xff0c;如 HTTP、FTP、SSH、MySQL 等&#xff0c;广泛应用于网络渗透测试和安全审计中。 目前该工具支持以下协议的爆破&#xff1a;ftp&#xff0c…

自动售货机是怎么知道你拿了啥的

南工程这学期&#xff0c;公共教学楼新增了自动售货机&#xff0c;不是传统售货机那样&#xff0c;在外面选择商品&#xff0c;然后掉出来。而是扫码或人脸识别之后&#xff0c;就可以打开冰柜门&#xff0c;自由挑选。 挺好奇起原理的&#xff0c;简单查了查&#xff1a; 这…

RabbitMQ学习笔记

目录 什么是MQ 什么是RabbitMQ RabbitMQ 使用场景 1. 服务解耦 2. 流量削峰 3. 异步调用 RabbitMQ 基本概念 RabbitMQ 安装 RabbitMQ Web界面管理 RabbitMQ六种工作模式 简单模式 SpringBootRabbitMQ实战 总结 工作模式 SpringBootRabbitMQ实战 发布订阅模式 …

【docker】了解什么是Docker

一、前言 最近&#xff0c;在学习如何部署项目的时候&#xff0c;老是出错误&#xff0c;然后朋友推荐了去学一下docker,然后自己就去学了【尚硅谷】的关于docker的教程视频&#xff0c;学完之后&#xff0c;感觉docker真的强&#xff0c;可以把我们做好的app的进行跨平台、快速…

零信任安全:重新思考数字世界的访问

目录 ​编辑 网络安全形势的演变 数字安全的变化 引入零信任安全 零信任的当今意义 了解零信任原则 零信任架构的核心概念 实施微分段 持续验证&#xff1a;积极主动的立场 与传统安全模型的对比 在现代企业中实施零信任 零信任实施基础知识 多重身份验证 (MFA) 的…