MyBatis中#{} 和 ${}有什么区别?

本文主要介绍MyBatis中#{}和${}的使用及区别。#{}使用预编译SQL,通过?占位,会自动拼接引号,性能高;${}是直接字符替换,存在SQL注入风险。同时说明了${}在排序、表名和字段名作为参数、like查询等场景的应用及解决办法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.#{} 和 ${} 的使用

1.1参数为Integer类型

image.png
image.png
观察打印日志:
输⼊的参数并没有在后⾯拼接,id的值是使⽤ ? 进⾏占位. 这种SQL 我们称之为"预编译SQL"
image.png
将 #{} 改为 ${}:
image.png
image.png
观察打印的日志:
即时SQL
image.png

1.2参数为String类型

image.png
image.png
打印日志:
image.png
将 #{} 改为 ${}:
image.png
image.png
打印日志:
image.png
参数依然是直接拼接在SQL语句中了, 但是字符串作为参数时, 需要添加引号 ’ ’ , 使⽤ ${} 不会拼接引号 ’ ’ , 导致程序报错:
image.png
image.png

2.#{} 和 ${} 的区别

#{} 使⽤的是预编译SQL, 通过 ? 占位的⽅式, 提前对SQL进⾏编译, 然后把参数填充到SQL语句中。 #{} 会根据参数类型, ⾃动拼接引号 ‘’${} 是直接进⾏字符替换, ⼀起对SQL进⾏编译. 如果参数为字符串, 需要加上引号 ‘’。

  1. #是预编译SQL,$是即时SQL,#性能更高

image.png
绝⼤多数情况下, 某⼀条 SQL 语句可能会被反复调⽤执⾏, 或者每次执⾏的时候只有个别的值不同(⽐如 select 的 where ⼦句值不同, update 的 set ⼦句值不同, insert 的 values 值不同)。如果每次都需要经过上⾯的语法解析, SQL优化、SQL编译等,则效率就明显不⾏了。
预编译SQL,编译⼀次之后会将编译后的SQL语句缓存起来,后⾯再次执⾏这条语句时,不会再次编译(只是输⼊的参数不同), 省去了解析优化等过程, 以此来提⾼效率。

  1. $ 存在SQL注入的风险

SQL注⼊:是通过操作输⼊的数据来修改事先定义好的SQL语句,以达到执⾏代码对服务器进⾏攻击的⽅法。
sql 注⼊代码: ’ or 1='1
image.png
image.png
image.png
image.png
$的使用场景

  1. 排序功能

image.png
image.png
此处 order 参数为String类型, 但是SQL语句中, 排序是不需要加引号 ‘’ 的, 使⽤ #{order} 查询时, desc 前后⾃动给加了引号, 导致 sql 错误:
image.png
改为$:
image.png
image.png
除此之外, 还有表名,字段名作为参数时, 也只能使⽤ ${}

  1. like查询

使用#:
image.png
image.png
image.png
改为$:
image.png
image.png
把 #{} 改成 可以正确查出来,但是{} 可以正确查出来, 但是可以正确查出来,但是{}存在SQL注⼊的问题, 所以不能直接使⽤ ${}。
解决办法: 使⽤ mysql 的内置函数 concat() 来处理,实现代码如下:
image.png
image.png
image.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值