为什么执行数据库操作时要对sql语句进行预编译?
因为如果不进行预编译操作,会有sql注入的安全问题
那么什么是sql注入呢?
SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
SQL注入代码解释
public class Sqlnjection {
public static void main(String[] args) {
//正常登录操作
login("asd","123456");
/*
*sql注入操作
*login(" ` or 1"," ` or 1");
*会导致非法用户直接登录,存在信息安全隐患
* */
}
//登录业务
public static void login(String uesrname, String password){
Connection connection= null;
Statement statement = null;
ResultSet resultSet = null;
try {
//获取数据库连接对象
connection = JdbcUtils.getConnection();
//创建数据库执行对象
statement = connection.createStatement();
String sql = "select * from users where name =`"+uesrname+"` and `password` =`"+password+"`";
resultSet=statement.executeQuery(sql);
if (resultSet==null)
System.out.println("登录失败");
while (resultSet.next()){
System.out.println(resultSet.getString("name"));
System.out.println(resultSet.getString("password"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtils.release(connection,statement,resultSet);
}
}
}
预编译PreparedStatement
预编译可以防止SQL注入,同时效率更高
预编译代码解释
public class TsetInsert {
public static void main(String[] args) {
Connection connection= null;
PreparedStatement preparedStatement=null;
ResultSet resultSet = null;
try {
//获取数据库连接对象
connection = JdbcUtils.getConnection();
//使用?占位符代替参数
String sql = "insert into users(id, `name`, `birthday`) values(?, ?)";
//预编译SQL,先写sql,然后不执行
preparedStatement = connection.prepareStatement(sql);
//手动给参数赋值
preparedStatement.setInt(1,4);//给第一个参数赋值为4
preparedStatement.setString(2,"abc");//给第二个参数赋值为abc
int i = preparedStatement.executeUpdate();
if (i>0){
System.out.println("插入成功");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JdbcUtils.release(connection,preparedStatement,null);
}
}
}
PreparedStatement 防止SQL注入的本质
把传递进来的参数当做字符,假设其中存在转义字符,比如说`会被直接转义(忽略)