MyBatis 中 ${ } 与 #{ } 对比

MyBatis 中 ${ } 与 #{ } 对比

文章目录

  • 背景
  • 区别
  • 附:MyBatis的 ${ } 存在安全问题,为什么又不得不用?

背景

动态 SQL 是 MyBatis 的一大特性。MyBatis 在对 SQL 语句进行预编译之前,会对 SQL 进行动态解析,解析为一个 BoundSQL 对象,也是在此处对多动态 SQL 进行处理的。在动态 SQL 解析阶段涉及到的元素有多种,本文主要分析 #{ }${ }的不同表现。

区别

${ }:字符串替换

#{ }:占位符

${ }在动态 SQL 解析阶段会直接进行变量替换,而#{ }会被解析成占位符,之后再进行变量替换。
#{ }${ }更安全,#{ }可以防止 SQL 注入,所以更多使用的是#{ }。(既然#{ }${ }看起来更好,那为什么还会保留${ }呢? 什么时候不得不使用${ }呢?)

附:MyBatis的 ${ } 存在安全问题,为什么又不得不用?

默认情况下,使用 #{} 格式的语法会导致 MyBatis 创建 PreparedStatement 参数并安全地设置参数(就像使用 ? 一样)。这样做更安全,更迅速,通常也是首选做法,不过有时你就是想直接在 SQL 语句中插入一个不转义的字符串。比如,像 ORDER BY,你可以这样来使用:

ORDER BY ${columnName}

这里 MyBatis 不会修改或转义字符串。

NOTE用这种方式接受用户的输入,并将其用于语句中的参数是不安全的,会导致潜在的 SQL 注入攻击,因此要么不允许用户输入这些字段,要么自行转义并检验。

上方便是 MyBatis 官方文档关于 $ 和 # 的描述

根据官方文档描述得知,#{ }会为变量加上单引号,比如:SELECT * FROM student WHERE name = "小明",这个语句中 “小明” 就是当作字符串来解析的,使用 #{ }是正合适的,但是当语句为 SELECT * FROM student ORDER BY id时,id 如果使用 #{ },语句会被解析成 SELECT * FROM student ORDER BY 'id',那么这种情况就不得不使用 ${}

你可能感兴趣的:(Mybatis)