为什么不再使用原生JDBC,而选择MyBatis之类的框架?

JDBC 中三种执行SQL的API

  • Statement:用于通用查询
  • PreparedStatement:继承至Statement接口,用于执行参数化查询
  • CallableStatement:继承至PreparedStatement接口,用于存储过程

1、问题:Statement与PreparedStatement的区别以及如何避免SQL注入?

  • Statement属于语句硬编码的方式来执行SQL语句
String name = "1' or '1' = '1";
String age = "1' or '1' = '1";
String sql = "select * from user where name = '" + name +"' and age = '"+ age +"'";
最终结果:select * from user where name = '1' or '1' = '1' and age = '1' or '1' = '1'
  • PreparedStatement:占位符/动态参数化
String sql = "select * from user where name = ? and age = ?";
String name = "1' or '1' = '1";
String age = "1' or '1' = '1";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, name);
preparedStatement.setString(2, age);
最终结果:select * from user where name = '1\' or \'1\' = \'1' and age = '1\' or \'1\' = \'1'

2、PreparedStatement

  • 如何创建:connection.prepareStatement()
  • 预编译(数据库会根据缓存策略缓存一些预编译Statement,若第二次使用时刚好预编译缓存中有,则不要重新编译,提升查询速度)
  • 动态参数化:参数filed相同的语句,会用“?”占位符代替,当在使用时,会用真正的参数值替换
  • 防止SQL注入式攻击:
    • 出现的原因:硬编码SQL语句,可以通过“恒为真”的语句来绕过原始Sql语句的过滤条件,如:SELECT * FROM users WHERE name = '" + userName + "' and pw = '"+ passWord +"'
    • 可以在传参数值时,传passWord = "1' OR '1'='1"或者userName = "1' OR '1'='1" 绕过过滤条件,最终sql语句会变成
      SELECT * FROM users WHERE name = '1' OR '1'='1’ and pw = '1' OR '1'='1'
      这条SQL语句“恒为真”,可以导出数据拖库。
    • PreparedStatement怎么防止的?
      • 预编译:在真正执行语句时,就算参数中有恶意语句,也会被当作是一个字段的属性值来处理而不会当作是一个sql指令。
      • 占位符:用值代替了”?“的位置,并且在值的两边加上了单引号,然后再把值当中的所有单引号替换成了斜杠单引号,说白了就是把值当中的所有单引号给转义了,这就达到了防止sql注入的目的,即PreparedStatement实现类的setString(),并在方法内部做了单引号的转义,而Statement不能防止sql注入,就是因为它没有把单引号做转义,而是简单粗暴的直接拼接字符串,所以达不到防止sql注入的目的。
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只打杂的码农

你的鼓励是对我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值