【JDBC】预编译SQL与防注入式攻击
在JDBC编程中,常用Statement、PreparedStatement 和 CallableStatement三种方式来执行查询语句,其中 Statement 用于通用查询, PreparedStatement 用于执行参数化查询,而 CallableStatement则是用于存储过程。
1、Statement
该对象用于执行静态的 SQL 语句,并且返回执行结果。 此处的SQL语句必须是完整的,有明确的数据指示。查的是哪条记录?改的是哪条记录?都要指示清楚。
通过调用 Connection 对象的 createStatement 方法创建该对象
查询:ResultSet excuteQuery(String sql)——返回查询结果的封装对象ResultSet. 用next()遍历结果集,getXX()获取记录数据。
修改、删除、增加:int excuteUpdate(String sql)——返回影响的数据表记录数.
2、PreparedStatement
SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。
可以通过调用 Connection 对象的 preparedStatement() 方法获取 PreparedStatement 对象
PreparedStatement 对象所执行的 SQL 语句中,参数用问号(?)来表示,调用 PreparedStatement 对象的 setXXX() 方法来设置这些参数. setXXX() 方法有两个参数,第一个参数是要设置的 SQL 语句中的参数的索引(从 1 开始),第二个是设置的 SQL 语句中的参数的值,注意用setXXX方式设置时,需要与数据库中的字段类型对应,例如mysql中字段为varchar,就需要使用setString方法,如果为Date类型,就需要使用setDate方法来设置具体sql的参数。
简单来说就是,预编译的SQL语句不是有具体数值的语句,而是用(?)来代替具体数据,然后在执行的时候再调用setXX()方法把具体的数据传入。同时,这个语句只在第一次执行的时候编译一次,然后保存在缓存中。之后执行时,只需从缓存中抽取编译过了的代码以及新传进来的具体数据,即可获得完整的sql命令。这样一来就省下了后面每次执行时语句的编译时间。
比如:
String sql="select Sname from stu where Sno=?"
PreparedStatement prestmt = conn.prepareStatement(sql);
prestmt.setString(1,sno);
prestmt.execute();
使用预编译的好处:
1:PreparedStatement比 Statement 更快
使用 PreparedStatement 最重要的一点好处是它拥有更佳的性能优势,SQL语句会预编译在数据库系统中。执行计划同样会被缓存起来,它允许数据库做参数化查询。使用预处理语句比普通的查询更快,因为它做的工作更少(数据库对SQL语句的分析,编译,优化已经在第一次查询前完成了)。
2:PreparedStatement可以防止SQL注入式攻击
SQL 注入攻击:SQL 注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的 SQL 语句段或命令,从而利用系统的 SQL 引擎完成恶意行为的做法。
比如:某个网站的登录验证SQL查询代码为:
|
1
|
strSQL = "SELECT * FROM users WHERE name = '" + userName + "' and pw = '"+ passWord +"';" |
恶意填入:
|
1
2
|
userName = "1' OR '1'='1";passWord = "1' OR '1'='1"; |
那么最终SQL语句变成了:
|
1
|
strSQL = "SELECT * FROM users WHERE name = '1' OR '1'='1' and pw = '1' OR '1'='1';" |
因为WHERE条件恒为真,这就相当于执行:
|
1
|
strSQL = "SELECT * FROM users;" |
因此可以达到无账号密码亦可登录网站。如果恶意用户要是更坏一点,用户填入:
|
1
|
strSQL = "SELECT * FROM users;" |
SQL语句变成了:
|
1
|
strSQL = "SELECT * FROM users WHERE name = 'any_value' and pw = ''; DROP TABLE users" |
这样一来,虽然没有登录,但是数据表都被删除了。
使用PreparedStatement的参数化的查询可以阻止大部分的SQL注入。在使用参数化查询的情况下,数据库系统不会将参数的内容视为SQL指令的一部分来处理,而是在数据库完成SQL指令的编译后,才套用参数运行,因此就算参数中含有破坏性的指令,也不会被数据库所运行。因为对于参数化查询来说,查询SQL语句的格式是已经规定好了的,需要查的数据也设置好了,缺的只是具体的那几个数据而已。所以用户能提供的只是数据,而且只能按需提供,无法更进一步做出影响数据库的其他举动来。
参考资料:
http://www.importnew.com/5006.html
【JDBC】预编译SQL与防注入式攻击的更多相关文章
- JDBC编程之预编译SQL与防注入式攻击以及PreparedStatement的使用教程
转载请注明原文地址: http://www.cnblogs.com/ygj0930/p/5876951.html 在JDBC编程中,常用Statement.PreparedStatement 和 ...
- JDBC编程之预编译SQL与防注入
在JDBC编程中,常用Statement.PreparedStatement 和 CallableStatement三种方式来执行查询语句,其中 Statement 用于通用查询, PreparedS ...
- jdbc预编译实现方式
jdbc预编译可以有两种方式: 方式一.jdbc自己实现的预编译,就是做一下特殊字符处理来防SQL注入,看PreparedStatement源码就可以了. public static void mai ...
- hibernate预编译SQL语句中的setParameter和setParameterList
使用预编译SQL语句和占位符參数(在jdbc中是?),可以避免由于使用字符串拼接sql语句带来的复杂性.我们先来简单的看下.使用预编译SQL语句的优点. 使用String sql = "se ...
- atitit.查看预编译sql问号 本质and原理and查看原生sql语句
atitit.查看预编译sql问号 本质and原理and查看原生sql语句 1. 预编译原理. 1 2. preparedStatement 有三大优点: 1 3. How to look gene ...
- mybatis中预编译sql与非预编译sql
预编译sql有缓存作用,非预编译没得 mybaits中带有#传参的有预编译左右,$没得 多用#传参 预编译语句的优势在于归纳为:一次编译.多次运行,省去了解析优化等过程:此外预编译语句能防止sql注入 ...
- 为什要使用预编译SQL?(转)
本文转自https://www.cnblogs.com/zouqin/p/5314827.html 今天在研发部技术大牛的指点下,我终于明白了为什么要使用SQL预编译的形式执行数据库JDBC:
- 为什要使用预编译SQL?
今天在研发部技术大牛的指点下,我终于明白了为什么要使用SQL预编译的形式执行数据库JDBC:
- jdbc预编译插入数据操作
package com.test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Prepare ...
随机推荐
- EF4.0和EF5.0增删改查写法区别
1 public T AddEntity(T entity) 2 { 3 //EF4.0的写法 4 添加实体 5 //db.CreateObjectSet<T>().AddObject(e ...
- Android 开发问题集合
1.屏幕横.竖切换 修改“AndroidManifest.xml”的android:screenOrientation 一般需要:landscape.portrait 2.修改应用名字 修改“Andr ...
- HDU 5313 Bipartite Graph (二分图着色,dp)
题意: Soda有一个n个点m条边的二分图, 他想要通过加边使得这张图变成一个边数最多的完全二分图. 于是他想要知道他最多能够新加多少条边. 注意重边是不允许的. 思路: 先将二分图着色,将每个连通分 ...
- angular js 实例参数学习
<!DOCTYPE html> <html> <head> <meta name="description" content=" ...
- django - 修改 request.POST的值
# querydict改为mutable data = data.copy() data.update({'key_list': DATA_UPLOAD_PARAMETER}) 默认的request. ...
- Oracle日常维护脚本
1.正常停库流程 ps -ef|grep LOCAL=NO|cut -c 9-15|xargs kill -9 shutdown immediate; 2.备份数据库 bac ...
- Tour
题意: 给n个点的坐标,求形成的最短的闭合回路. 分析: 经典问题,dp[i][j]表示有1-i点再由j回到1点的最短距离,i点有两种情况,在去的路径上 dp[i][j]=min(dp[i][j],d ...
- Shell获取Aix/linux/unix机器上db2和os的信息并上传到指定服务器
(之前写过一篇类似的文章,当时传输文件用的是ftp,因为项目觉得ftp不够安全所以这次换成了scp,同时对脚本的一些地方也做了一些调整) 其实做这个东西还是因为项目的需求,需要获取某些机器(目前主要是 ...
- <转>DNS服务系列之二:DNS区域传送漏洞的安全案例
DNS区域传送(DNS zone transfer)指的是一台备用服务器使用来自主服务器的数据刷新自己的域(zone)数据库.这为运行中的DNS服务提供了一定的冗余度,其目的是为了防止主的域名服务器因 ...
- 关于display显示 linux
export DISPLAY=ipaddressofyourmachineorpc:0.0 如果要在本来的机器上显示,使用 export DISPLAY=localhost:0