Statement操作数据库的弊端
数据库连接被用于向数据库服务器发送命令和SQL语句,并接受数据库服务器返回的结果
- 其实一个数据库连接就是一个Socket连接
在java.sql包中有三个接口分别定义了对数据库的调用的不同方式:
-
Statement: 用于执行静态SQL语句,并返回它所生成结果的对象
-
PreparedStatement: 预编译SQL语句并将SQL语句存储在此对象中,可以使用此对象多次高效的执行该语句
-
CallableStatement: 用于执行SQL存储过程
- 这个接口我们具体会在框架中学习
我们一般不使用Statement操作数据库,因为使用Statement操作数据库表存在一定的弊端(所以我们一般都是使用PreparedStatement代替Statement来操作数据库)
-
那么使用Statement接口操作数据库存在哪些弊端?
-
存在拼串操作 – 很繁琐
-
存在SQL注入的问题
-
SQL注入: 利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入的数据中注入非法的SQL语句段或者命令的行为.
- eg:(我们举一个出现SQL注入的实际情况)
"SELECT user,password FROM user_table WHERE user = "+ user +" AND password = "+ password
-
这个时候如果user变量为’1’ or ‘,并且password变量为’=1 or ‘1’ = ‘1’ ,那么这个时候就会出现SQL注入的问题,为什么? 这里我们在Java程序中看不出来什么,但是如果这条语句被具体执行在MySQL中,这个时候就会出现问题:(如下:)
SELECT user,password FROM user WHERE user = '1' OR 'AND PASSWORD = '= 1 OR '1' = '1';
- 这个时候很明显,这个时候WHERE子句中的判断条件是很成立的,因为后面最后一个OR的右边有 ‘1’ = ‘1’,而这里’1’ = ‘1’的结果很明显恒等于1,那么这里OR的两边只要有一个是1,那么这个关系是的返回结果就是1 —> 那么这个时候即使数据库中没有user为’1’ or ‘的记录,并且也没有对应的password为’=1 or ‘1’ = '1’的记录,但是这个时候我们还是查找出了结果,这个时候如果登录检查中的判断条件是只要从数据库中查询出的结果不为null那么就可以登录成功的话,这个时候这种情况下我们就是可以进入数据库的,因为这个时候是会查询出表中的所有记录的,这个时候就是一种SQL注入的问题
- 我们将这个问题引申一下: 如果这个时候我们执行的是一个删除表中记录的操作,这个时候我们传入了同样的参数,那么这个时候会是什么后果? —> 后果就是WHERE条件很成立,或者说就等同于DELETE FROM语句没有加WHERE子句,就会将表中的所有数据全部删除掉,这个时候就体现出了SQL注入问题的可怕之处,想一想,如果别人想后端发送一条指令,这个时候就可以将数据表中的全部记录都删除掉,这个时候是多么可怕的问题
- 这个时候很明显,这个时候WHERE子句中的判断条件是很成立的,因为后面最后一个OR的右边有 ‘1’ = ‘1’,而这里’1’ = ‘1’的结果很明显恒等于1,那么这里OR的两边只要有一个是1,那么这个关系是的返回结果就是1 —> 那么这个时候即使数据库中没有user为’1’ or ‘的记录,并且也没有对应的password为’=1 or ‘1’ = '1’的记录,但是这个时候我们还是查找出了结果,这个时候如果登录检查中的判断条件是只要从数据库中查询出的结果不为null那么就可以登录成功的话,这个时候这种情况下我们就是可以进入数据库的,因为这个时候是会查询出表中的所有记录的,这个时候就是一种SQL注入的问题
-
-
那么在Java中我们要如何解决SQL注入的问题?
对于java而言,要防范SQL注入,只要用PreparedStatement代替Statement接口就可以了
补充:
PreparedStatement是Statement接口的一个子接口