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

发布时间:2021-12-07 11:33:36 作者:小新
来源:亿速云 阅读:212
# 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 = ?

1.2 ${}(字符串拼接)


2. 关键差异详解

特性 #{} ${}
SQL注入风险 安全(自动参数化) 高风险(直接拼接)
预编译支持
参数类型处理 自动类型转换(如Date→Timestamp) 原样输出
动态表名/列名 不支持 支持
性能 通常更优(数据库可缓存执行计划) 每次需重新解析SQL

3. 安全风险案例

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>

4. 适用场景指南

推荐使用#{}的情况

谨慎使用${}的场景

  1. 动态表名/列名
    
    <select id="queryByField" resultType="map">
     SELECT * FROM ${tableName} ORDER BY ${columnName}
    </select>
    
  2. SQL函数/特殊语法
    
    <select id="findRecent" resultType="User">
     SELECT * FROM users 
     WHERE create_time > DATE_SUB(NOW(), INTERVAL ${days} DAY)
    </select>
    

5. 进阶技巧

混合使用案例

<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与数据库字段的转换
}

6. 总结

选择原则 说明
默认使用#{} 保障安全性,预防SQL注入
${}仅用于非值部分 表名、列名等元数据操作
动态SQL优先用OGNL表达式 <if>, <choose>等标签更安全

正确理解这两种占位符的区别,能够帮助开发者在保证系统安全性的同时,灵活应对各种复杂SQL场景。 “`

推荐阅读:
  1. mybatis和hikariCP的配置方法
  2. mybatis框架下xml文件中foreach的使用方法

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

mybatis

上一篇:mysql如何查看注释

下一篇:Hyperledger fabric Chaincode开发的示例分析

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》