# 对传入的参数视为字符串,会首先对sql语句进行预编译,使用PreparedStatement ,sql语句中有?存在
举个栗子:
select * from user where id = #{id},传入id值为5,sql语句预编译为 select * from user where id = ?
那么传过来的SQL语句就是 select * from user where id = ‘5’;
实例mapper中的sql语句
<!-- 根据主键删除teacher-->
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
delete from t_teacher
where id = #{id,jdbcType = BIGINT}
</delete>
该语句执行时spring日志打印信息
==> Preparing: delete from t_teacher where id = ?
==> Parameters: 10(Long)
<== Updates: 1
$ 将不会将传入的值进行预编译
select * from user where id = ${id},传入id值为5,
那么传入后的SQL语句就是 select * from user where id = 5;
实例mapper中的sql语句
<!-- 根据主键list删除teacher-->
<delete id="deleteByPrimaryKeyList" parameterType="java.util.List">
delete from t_teacher
where id in
<foreach collection="list" item="id" open="(" separator="," close=")">
${id}
</foreach>
</delete>
该语句执行时spring日志打印信息
==> Preparing: delete from t_teacher where id in ( 43 , 44 )
==> Parameters:
<== Updates: 2
# 能在很大程度上防止sql注入,而 $ 则不行。
对于sql语句:select * from user where account = #{account} and password = #{pwd},
如果前台传来的账户名是“a”,密码是 “1 or 1=1”,用#的方式就不会出现sql注入,sql语句为
select * from user where account = ‘a’ and password = ‘1 or 1=1’ 查出account为a,password为1 or 1=1的用户
,而如果换成$方式,sql语句就变成了
select * from user where account = a and password = 1 or 1=1 查出全部用户数据
这样会产生sql注入的情况,比较不安全
MyBatis排序时使用order by 动态参数时需要注意,用$而不是#
在进行模糊查询时,需要进行模糊匹配,采用$可以使用like ‘%${remark}%’ 方法,因为${}不会在
<!-- 根据备注模糊查询teacher-->
<select id="selectByRemark" parameterType="java.lang.String" resultMap="BaseResultMap">
select <include refid="Base_Column_List"/>
from t_teacher
where 1 = 1
<if test="remark != null and remark != ''">
and remark like CONCAT('%',#{teacher.remark},'%')
</if>
</select>
官方文档
默认情况下,使用 #{} 格式的语法会导致 MyBatis 创建 PreparedStatement 参数占位符并安全地设置参数(就像使用 ? 一样)。 这样做更安全,更迅速,通常也是首选做法,不过有时你就是想直接在 SQL 语句中插入一个不转义的字符串。 比如,像 ORDER BY,你可以这样来使用:
ORDER BY ${columnName}
这里 MyBatis 不会修改或转义字符串。
当 SQL 语句中的元数据(如表名或列名)是动态生成的时候,字符串替换将会非常有用。
如果你想通过任何一列从表中 select 数据时,不需要像下面这样写:
@Select(“select * from user where id = #{id}”)
User findById(@Param(“id”) long id);
@Select(“select * from user where name = #{name}”)
User findByName(@Param(“name”) String name);
@Select(“select * from user where email = #{email}”)
User findByEmail(@Param(“email”) String email);
// and more “findByXxx” method
可以只写这样一个方法:
@Select(“select * from user where ${column} = #{value}”)
User findByColumn(@Param(“column”) String column, @Param(“value”) String value);