MyBatis的#和$符号详解(Java面试)
🤟致敬读者
- 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉
📘博主相关
- 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息
文章目录
- Java面试中MyBatis的#和$符号详解
- 1. **`#{}`(预编译占位符)**
- 2. **`${}`(字符串直接替换)**
- ⚠️ 关键对比总结
- 🛡️ 使用建议
- 🔍 面试回答要点
📃文章前言
- 🔷文章均为学习工作中整理的笔记。
- 🔶如有错误请指正,共同学习进步。
Java面试中MyBatis的#和$符号详解
在Java的MyBatis框架中,#{}
和${}
是处理SQL参数的两种关键符号,它们在底层实现、安全性和使用场景上有显著区别:
1. #{}
(预编译占位符)
- 实现原理
转换为JDBC的PreparedStatement
参数占位符?
,执行时通过setXxx()
方法安全传参。SELECT * FROM user WHERE id = #{userId} → 实际执行:SELECT * FROM user WHERE id = ? (参数值安全注入)
- 安全性
天然防止SQL注入(参数值不会作为SQL片段解析)。 - 数据类型处理
自动处理类型转换(如字符串添加引号、日期格式化)。 - 适用场景
所有数据值场景(WHERE条件值、INSERT/UPDATE值等)。
2. ${}
(字符串直接替换)
- 实现原理
直接替换为参数值的字符串(不做预编译处理)。SELECT * FROM ${tableName} ORDER BY ${column} → 可能生成:SELECT * FROM orders ORDER BY create_time
- 安全性
有SQL注入风险(若参数值来自用户输入且未过滤)。ORDER BY ${input} // 若input="1; DROP TABLE user--" 会导致灾难!
- 数据类型处理
需手动处理类型(如字符串需自行添加引号)。 - 适用场景
动态SQL关键字/结构(表名、列名、ORDER BY子句等无法预编译的位置)。
⚠️ 关键对比总结
特性 | #{} | ${} |
---|---|---|
底层机制 | 预编译占位符 (? ) | 字符串直接替换 |
SQL注入风险 | ✅ 安全 | ❌ 高风险(需严格校验参数) |
处理数据类型 | 自动添加引号/格式转换 | 需手动处理(如字符串加' ' ) |
性能 | 通常更优(数据库可缓存执行计划) | 每次生成新SQL |
适用场景 | 数据值(用户输入、条件值等) | SQL结构(表名、列名、动态SQL片段) |
🛡️ 使用建议
-
默认首选
#{}
只要涉及数据值(特别是用户输入),强制使用#{}
确保安全。<!-- 安全示例 --> <select id="findUser">SELECT * FROM user WHERE name = #{name} AND age > #{minAge} <!-- 正确做法 --> </select>
-
谨慎使用
${}
仅用于动态标识符(非数据),且必须做参数校验:<!-- 动态表名示例(需校验tableName合法性) --> <select id="selectFromTable">SELECT * FROM ${tableName} WHERE role = #{role} <!-- 值仍用#{} --> </select>
-
禁止将用户输入直接用于
${}
若不可避免(如动态排序字段),应在代码层白名单校验:// Java层校验示例 public String safeOrderColumn(String input) {Set<String> validColumns = Set.of("name", "age", "create_time");return validColumns.contains(input) ? input : "id"; // 默认安全值 }
🔍 面试回答要点
- 根本区别:
#{}
是参数化查询(安全),${}
是字符串拼接(危险)。 - 安全原则:
“数据值必用#{}
,动态结构慎用${}
,用户输入绝不用${}
”。 - 漏洞案例:
${}
未过滤导致"1; DELETE FROM user"
会执行恶意SQL。 - 动态表名解决方案:
用${}
但需在业务层校验表名合法性(如映射预定义表名)。
📌 总结:MyBatis中SQL安全的核心在于——所有数据值必须通过
#{}
传递,仅在必要时(如动态表结构)对${}
进行严格受控的使用。
📜文末寄语
- 🟠关注我,获取更多内容。
- 🟡技术动态、实战教程、问题解决方案等内容持续更新中。
- 🟢《全栈知识库》技术交流和分享社区,集结全栈各领域开发者,期待你的加入。
- 🔵加入开发者的《专属社群》,分享交流,技术之路不再孤独,一起变强。
- 🟣点击下方名片获取更多内容🍭🍭🍭👇