您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# MyBatis中的#{}和${}有什么区别
## 引言
在MyBatis框架中,`#{}`和`${}`是两种常见的参数占位符语法,它们在SQL语句中用于动态替换参数值。虽然表面上看功能相似,但底层实现机制、安全性和适用场景存在显著差异。本文将深入解析两者的区别,并通过代码示例帮助开发者正确选择和使用。
---
## 1. 核心机制对比
### 1.1 `#{}`(预编译占位符)
- **实现原理**
采用预编译(PreparedStatement)机制,运行时会被替换为`?`占位符,参数值通过JDBC的set方法安全注入。
- **示例代码**
```xml
<select id="findUserById" resultType="User">
SELECT * FROM users WHERE id = #{userId}
</select>
实际执行SQL:
SELECT * FROM users WHERE id = ?
${}
(字符串拼接)实现原理
直接进行字符串替换(Statement),参数值按原样拼接到SQL语句中。
示例代码
<select id="findUserByName" resultType="User">
SELECT * FROM users WHERE name = '${userName}'
</select>
若userName
值为"John"
,最终SQL为:
SELECT * FROM users WHERE name = 'John'
特性 | #{} |
${} |
---|---|---|
SQL注入风险 | 安全(自动参数化) | 高风险(直接拼接) |
预编译支持 | 是 | 否 |
参数类型处理 | 自动类型转换(如Date→Timestamp) | 原样输出 |
动态表名/列名 | 不支持 | 支持 |
性能 | 通常更优(数据库可缓存执行计划) | 每次需重新解析SQL |
<!-- 危险写法 -->
<select id="login" resultType="User">
SELECT * FROM users
WHERE username = '${username}' AND password = '${password}'
</select>
攻击者输入:
username: admin' --
password: any
最终执行:
SELECT * FROM users WHERE username = 'admin' --' AND password = 'any'
<!-- 正确写法 -->
<select id="login" resultType="User">
SELECT * FROM users
WHERE username = #{username} AND password = #{password}
</select>
#{}
的情况${}
的场景
<select id="queryByField" resultType="map">
SELECT * FROM ${tableName} ORDER BY ${columnName}
</select>
<select id="findRecent" resultType="User">
SELECT * FROM users
WHERE create_time > DATE_SUB(NOW(), INTERVAL ${days} DAY)
</select>
<select id="dynamicQuery" resultType="User">
SELECT * FROM ${tablePrefix}_users
WHERE status = #{status}
<if test="orderBy != null">
ORDER BY ${orderBy}
</if>
</select>
通过自定义TypeHandler
可增强#{}
的处理能力:
@MappedTypes(JSONObject.class)
public class JsonTypeHandler extends BaseTypeHandler<JSONObject> {
// 实现JSON与数据库字段的转换
}
选择原则 | 说明 |
---|---|
默认使用#{} | 保障安全性,预防SQL注入 |
${}仅用于非值部分 | 表名、列名等元数据操作 |
动态SQL优先用OGNL表达式 | <if> , <choose> 等标签更安全 |
正确理解这两种占位符的区别,能够帮助开发者在保证系统安全性的同时,灵活应对各种复杂SQL场景。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。