Mybatis中防止Sql注入

一、什么是Sql注入

sql注入是一种代码注入技术,将恶意的sql插入到被执行的字段中,以不正当的手段多数据库信息进行操作。

在jdbc中使用一般使用PreparedStatement就是为了防止sql注入。

比如代码 :"select * from user where id =" + id;
正常执行不会出现问题,一旦被sql注入,比如将传入参数id=“3 or 1 = 1”,那么sql会变成
"select * from user where id = 3 or 1 = 1",这样全部用户信息就一览无遗了。

二、MyBatis中防止sql注入

下面是Mybatis的两种sql。

  <select id="selectByPrimaryKey" resultMap="BaseResultMap"         
                        parameterType="java.lang.Integer" >
    select 
    <include refid="Base_Column_List" />
    from user
    where id = #{id,jdbcType=INTEGER}
  </select>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" 
                         parameterType="java.lang.Integer" >
    select 
    <include refid="Base_Column_List" />
    from user
    where id = ${id,jdbcType=INTEGER}
  </select>

可以很清楚地看到,主要是#和$的区别。

# 将sql进行预编译"where id = ?",然后底层再使用PreparedStatement的set方法进行参数设置。

$ 将传入的数据直接将参数拼接在sql中,比如 “where id = 123”。

因此,#与$相比,#可以很大程度的防止sql注入,因为对sql做了预编译处理,因此在使用中一般使用#{}方式。

三、演示

在项目中配置log4j。方便查看sql日志。

#方式

查看日志,sql进行了预编译,使用了占位符,防止了sql注入。  
[cn.jxust.cms.dao.UserMapper.selectByPrimaryKey] - ==>  Preparing: select id, stuId, username, password, type, info from user where id = ? 
  [cn.jxust.cms.dao.UserMapper.selectByPrimaryKey] - ==> Parameters: 1(Integer)
  [cn.jxust.cms.dao.UserMapper.selectByPrimaryKey] - <==      Total: 1

$方式

$传入的数据直接显示在sql中
 [cn.jxust.cms.dao.UserMapper.selectByPrimaryKey] - ==>  Preparing: select id, stuId, username, password, type, info from user where id = 1 
  [cn.jxust.cms.dao.UserMapper.selectByPrimaryKey] - ==> Parameters: 
  [cn.jxust.cms.dao.UserMapper.selectByPrimaryKey] - <==      Total: 1

​

附:使用$方式时,需要在mapper接口中使用@Param注解。否则会报There is no getter for property named 'id' in 'class java.lang.Integer'错误

User selectByPrimaryKey(@Param(value = "id") Integer id);

 

参考资料:

https://www.cnblogs.com/mmzs/p/8398405.html

### 如何在 MyBatis防止 SQL 注入的最佳实践 #### 使用 `#{}` 占位符 为了防止 SQL 注入,在编写 MyBatis 的映射文件时应始终使用 `#{}` 占位符来代替字符串拼接。`#{}` 将会把传入的参数视为预编译语句中的占位符,从而避免恶意输入被当作 SQL 片段执行[^1]。 ```xml <select id="getUserById" parameterType="int" resultType="User"> SELECT * FROM users WHERE id = #{id} </select> ``` #### 避免使用 `${}` 插值表达式 虽然 `${}` 提供了动态替换的功能,但它直接将变量值插入到 SQL 语句中而不做任何转义处理,这使得应用程序易受 SQL 注入攻击的影响。因此应当谨慎使用,并仅限于那些确实需要动态构建查询条件的情况,比如表名或列名[^4]。 #### 参数校验与清理 除了依赖框架本身的安全机制外,还应该对来自客户端的所有输入数据进行全面验证和清理工作。可以通过正则表达式或其他手段去除潜在危险字符(如单引号、分号等),确保只有合法的数据能够进入数据库操作流程。 #### 利用 Prepared Statements 和存储过程 当涉及到复杂的业务逻辑或者频繁访问相同模式的数据集时,考虑采用预编译好的 PreparedStatement 或者调用已有的存储过程来进行交互。这种方式不仅提高了性能,同时也增强了安全性,因为它们内部实现了有效的参数绑定机制。 #### 定期审查代码库并更新依赖版本 随着技术的发展,新的漏洞可能会不断涌现出来;定期审计现有项目的源码质量,及时修补发现的问题所在之处非常重要。另外也要关注官方发布的补丁信息,适时升级所使用的第三方组件至最新稳定版以获得更好的防护效果[^3]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值