Mybatis #{} 和 ${}区别,使用场景,LIKE模糊查询避免SQL注入

#{} 和 ${}区别

#{} 和 {},其最大的区别则是#{}方式能够很大程度防止sql注入(安全),{}方式无法防止Sql注入

sql注入:

Sql注入指的是程序解析时会将你传入的参数作为原来SQL语句的一部分,打乱原来SQL的结构,而通常我们只是需要传入一个参数而已.

#{} 预编译占位符

  1. #{}表示一个占位符号 相当于 jdbc中的 ? 符号
    #{}实现的是向prepareStatement中的预处理语句中设置参数值,sql语句中#{}表示一个占位符即?
  2. #{}将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:
sql 复制代码
select * from user where id= #{user_id}
# 传入 3 
# 解析成sql
select * from user where id= where id="11"
  1. 如果sql语句中只有一个参数,此时参数名称可以随意定义,如果sql语句有多个参数,此时参数名称应该是与当前表关联实体类的属性名或则Map集合关键字,不能随便写,必须对应!

$ {} 字符串拼接

  1. $ {}将传入的数据直接显示生成在sql中。如:
sql 复制代码
select * from user where id= $ {user_id}
# 传入的值是 3 
# 解析成sql
select * from user where id= 3
  1. {value}中value值有限制只能写对应的value值不能随便写,因为{}不会自动进行jdbc类型转换

必须使用 ${} 场景

简单来说,在JDBC不支持使用占位符的地方,都可以使用${},比如动态指定表名,指定动态排序参数

  1. 表名或列名动态替换(表名 / 列名不能作为预编译参数)
sql 复制代码
<select id="getAllFromTable" resultType="map">
  SELECT * FROM ${tableName} WHERE status = 'active'
</select>

为什么不能若使用#{}:
原因:若使用#{} 会生成 SQL SELECT * FROM 'user_table' WHERE ...(引号导致语法错误)

  1. SQL 片段拼接:如排序字段(ORDER BY)
sql 复制代码
<select id="getUsersOrderBy" resultType="User">
  SELECT * FROM users ORDER BY ${sortField} ${sortOrder}
</select>

为什么不能若使用#{}:
原因:若使用#{}:会生成 SQL ORDER BY 'username' ASC(引号导致排序失败)

  1. 原生 SQL 函数参数:如日期格式化函数
sql 复制代码
<select id="getUsersByDate" resultType="User">
  SELECT * FROM users WHERE create_time LIKE '${formattedDate}%'
</select>

LIKE模糊查询

永远不要在 LIKE 语句中直接使用 ${} 拼接通配符

使用 ${} 模糊查询

sql 复制代码
<select id="searchUsers" resultType="User">
  SELECT * FROM users WHERE username LIKE '%${keyword}%'
</select>
# 用户输入 ' OR '1'='1
# SQL 将变为
SELECT * FROM users WHERE username LIKE '%' OR '1'='1%' # 此时条件恒为真

优先方案:Java 端拼接 % + #{}。

java 复制代码
// Java代码
String keyword = "%" + searchTerm + "%";
userMapper.searchUsers(keyword);
xml 复制代码
// XML映射
<select id="searchUsers" resultType="User">
  SELECT * FROM users WHERE username LIKE #{keyword}
</select>

替代方案: 标签 + #{}。

xml 复制代码
<select id="searchUsers" resultType="User">
  <bind name="pattern" value="'%' + keyword + '%'" />
  SELECT * FROM users WHERE username LIKE #{pattern}
</select>

性能差异

#{} 利用预编译缓存,批量插入 或 更新时性能更优。

${} 每次需重新解析 SQL,频繁调用时可能影响性能。

相关推荐
偶遇急雨洗心尘16 分钟前
记录一次服务器迁移时,数据库版本不一致导致sql函数报错和系统redirect重定向丢失域名问题
运维·服务器·数据库·sql
Arva .38 分钟前
MySQL 的存储引擎
数据库·mysql
Logic10144 分钟前
《Mysql数据库应用》 第2版 郭文明 实验5 存储过程与函数的构建与使用核心操作与思路解析
数据库·sql·mysql·学习笔记·计算机网络技术·形考作业·国家开放大学
小二·1 小时前
MyBatis基础入门《十六》企业级插件实战:基于 MyBatis Interceptor 实现 SQL 审计、慢查询监控与数据脱敏
数据库·sql·mybatis
bing.shao1 小时前
Golang WaitGroup 踩坑
开发语言·数据库·golang
专注VB编程开发20年1 小时前
C#内存加载dll和EXE是不是差不多,主要是EXE有入口点
数据库·windows·microsoft·c#
小二·1 小时前
MyBatis基础入门《十二》批量操作优化:高效插入/更新万级数据,告别慢 SQL!
数据库·sql·mybatis
何中应1 小时前
【面试题-6】MySQL
数据库·后端·mysql·面试题
路遥_131 小时前
银河麒麟 V10 安装部署瀚高数据库 HighGoDB 4.5 全流程(统信UOS Server 20同理)
数据库
TDengine (老段)1 小时前
从关系型数据库到时序数据库的思维转变
大数据·数据库·mysql·时序数据库·tdengine·涛思数据·非关系型数据库