Mybatis中#{}与${}的使用区别

一、核心差异概览 

对比维度#{} (预编译占位符)${} (字符串拼接符)
处理方式参数化查询,预编译处理直接字符串替换
安全性天然防SQL注入存在SQL注入风险
性能支持预编译缓存,重复查询效率更高每次生成新SQL,无法复用执行计划
数据类型自动类型转换(Date/Number等)需要手动处理特殊类型
使用场景常规参数传递(WHERE条件值)动态表名/列名、SQL关键字拼接等特殊场景

二、底层原理对比

1. #{}工作原理

原始Mapper语句

SELECT * FROM users WHERE name = #{userName}

实际执行流程

1. 解析为预编译SQL:

SELECT * FROM users WHERE name = ?

2. 通过PreparedStatement.setString(1, userName)设置参数

3. 数据库执行参数化查询

2. ${}工作原理

原始Mapper语句

SELECT * FROM ${tableName} ORDER BY ${sortField}

执行时直接拼接 

SELECT * FROM user_tbl ORDER BY create_time

三、举例说明

在MyBatis中,对于sql:SELECT * FROM users WHERE name = #{userName},当userName值为"aaor 1=1"时,MyBatis会通过预编译机制进行安全处理,具体过程如下:

1、SQL解析阶段
MyBatis会将原始SQL转换为预编译语句:

SELECT * FROM users WHERE name = ?

2、参数传递阶段
通过PreparedStatement设置参数:

pstmt.setString(1, "aa' or 1=1");  // JDBC自动处理特殊字符

3、最终执行SQL
实际发送到数据库的查询为:(单引号被转义为两个单引号,具体转义方式因数据库而异)

SELECT * FROM users WHERE name = 'aa'' and 1=1'

对比之下,若使用${}来处理时:SELECT * FROM users WHERE name = ${userName},当userName值为"'aa' OR 1=1"时,实际执行的sql为:

SELECT * FROM users WHERE name = 'aa' OR 1=1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值