在 MyBatis 中,# 和 $ 的核心区别是:#{} 是预编译参数绑定(安全),${} 是字符串直接替换(有 SQL 注入风险)。


一、#{} —— 预编译占位符(推荐 ✅)

SELECT * FROM user WHERE id = #{id}

实际执行的 SQL:

SELECT * FROM user WHERE id = ?

参数通过 PreparedStatement 设置,自动处理类型和转义。

优点

• ✅ 防止 SQL 注入

• ✅ 自动进行类型转换

• ✅ 可读性好,MyBatis 首选方式


二、${} —— 字符串直接替换(慎用 ⚠️)

SELECT * FROM ${tableName} WHERE id = #{id}

假设 tableName = “user” ,实际生成 SQL:

SELECT * FROM user WHERE id = ?

⚠️ 但如果传入的是恶意值,比如:

tableName = “user; DROP TABLE user;”

就会变成:

SELECT * FROM user; DROP TABLE user; – WHERE id = ?

这就是 SQL 注入!


三、对比总结

对比项 #{} ${}
处理方式 预编译占位符 ? 字符串直接拼接
SQL 注入 ✅ 安全 ❌ 有风险
是否加引号 自动加 不会自动加
适用场景 参数值(WHERE、SET) 表名、列名、排序字段


四、什么时候必须用 ${}?

✅ 动态表名 / 列名

SELECT * FROM ${tableName}

✅ ORDER BY 动态字段

SELECT * FROM user ORDER BY ${column} ${order}

⚠️ 这种情况一定要在 Java 代码中做 白名单校验,不能从前端直接传!


五、最佳实践 ✅

// 错误示例(危险)
String orderBy = request.getParameter(“orderBy”); // “id; DROP TABLE user”

// 正确示例(白名单)
if (!“id”.equals(orderBy) && !“name”.equals(orderBy)) {
orderBy = “id”;
}


六、一句话记忆 🧠

能用 #{} 就绝不用 ,{},{} 只用于表名、字段名,并且必须做校验。

如果你有具体的 SQL 场景,我可以帮你判断该用哪个 👍

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐