目录
前言
前面讲到了SQL注入问题的不安全,主要原因就是由于Statement对象不安全!要解决SQL注入问题就不能使用Statement对象。
PreparedStatement对象
作用:
-
防止SQL注入,效率更高
让我们来看看这个PreparedStatement对象的定义:
可依法向PreparedStatement本质上是一个接口,继承了Statement父类(继承就是用来扩展和改变父类的一些东西!)
代码实现
核心代码:
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = JDBCUtils.getConnection();
// 使用? 占位符代替参数
String sql = "insert into student values(?,?,?,?,?)";
// 预编译sql,先写sql,然后不执行
preparedStatement = connection.prepareStatement(sql);
// 手动给参数赋值
// 1是传入参数的位置(指的就是第一个?的参数)
// 后面的是参数的内容
preparedStatement.setString(1,"2015134");
preparedStatement.setString(2,"小李");
preparedStatement.setString(3,"男");
preparedStatement.setInt(4,99);
preparedStatement.setString(5,"MS");
// 执行
int i = preparedStatement.executeUpdate();
if (i > 0){
System.out.println("插入成功!");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.release(connection,preparedStatement,null);
}
全部代码在这JDBC工具类这篇文章中有给出。
说白了就是先写sql语句,并把参数值设为?(泛型),然后在执行之前把参数设进去!
PreparedStatement防止注入演示
public static void main(String[] args) throws SQLException {
login("'or'1=1","'or'1=1");
}
public static void login(String Sno,String Sname) throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try{
// 获取数据库连接
connection = JDBCUtils.getConnection();
// 改成PreparedStatement写法
// 假设其中存在转义字符,比如'会被直接转义
// 注意:MyBatis底层就是这个
String sql = "select * from student where Sno =? and Sname =?";
statement = connection.prepareStatement(sql);
statement.setString(1,Sno);
statement.setString(2,Sname);
resultSet = statement.executeQuery();
在上一篇SQL注入文中我们使用Statement对象进行同样的查询能查出结果,这次查询的结果为空。说明使用PreparedStatement对象能防止SQL注入问题。
PreparedStatement防止SQL注入的本质:把传递进来的参数当作字符!