JDBC原生编程以及SQL注入详解
SQL注入;
一SQL注入:通过在Web表单中输入(恶意)SQL语句而连接到一个存在安全漏斗的网站上的数据库,而不是按照设计者意图去执行SQL语句;
例如:
String username="hello' or 1='1";
String password ="123456";
String sql=” "SELECT * FROM t_users WHERE username='"+username+"' AND password = '"+password+"'" ;
#即使数据库里没有username=’hello’这个字段,也是可以查找到的;
-
防止SQL注入的方式:
-
使用PreparedStatement,它内置了处理SQL注入的能力,只要使用其setXXX()方法传值即可;
好处:a,提高性能;b,提高了安全性;
原理:使用PreparedStatement去执行sql语句时,会提前对sql语句进行预编译,将传入的参数以字符串的形式去处理,则会在参数两边自动加上’ ’号,而使用statement则是直接通过人工字符串拼接的方式去写sql语句à容易导致SQL注入
preparedStatement中的SetString()方法中存在一个for循环,对字符串参数上的每一位字符进行遍历,并用Switch..case进行判断,当出现特殊字符时(” ‘ ! )等,就进行转义,转义之后组合而形成的新的参数与数据库中的字段不匹配,也就有效防止了SQL注入;
-
Mybatis框架中的mapper方式中使用#也可以有效防止sql注入,原理与preparedStatement一致,而使用$则无法防止SQL注入;
二:原生JDBC连接数据库开发步骤
Connection Conn=null;
PreparedStatement ps=null;
ResultMap rs=null;
Try{
//1.使用反射加载数据库驱动
Class.forName(“com.mysql.cj.jdbc.Driver”);
//2.获取数据库连接对象
Conn=DriverManager.getConnection(“mysql:jdbc:///数据库名","数据库用户名","数据库用户密码");
//3.准备SQL语句,并进行预编译
String sql=”select * from t_users where username=? And password=?”;
Ps=Conn.preparedStatement(sql);
Ps.setString(1,user.getUsername());
Ps.setString(2,user.getPassword());
//4.执行SQL语句
//int count=Ps.executeUpdate();//执行增删改执行的方法,返回受影响的行数
Rs=Ps.executeQuery();//执行查询语句时使用的方法,返回结果集
//遍历结果集
While(Rs.next()){//该方法的返回值表示是否还有下一个结果集
User.setId(Rs.getLong("id"));
Return true;
}
}finally{
//5.关闭资源
Try{
If(Rs!=null){
Rs.close();
}
}finally{
Try{
If(Ps!=null){
Ps.close();
}
}finally{
If(Conn!=null){
Conn.close();
}
}
}
}