1.SQL注入问题
在以前过程中,总是采取拼接SQL语句的方式,来实现数据的增删改查!
String Sql=select * from user where username="" and password=""
由于没有对拼接的字符进行检查,很容易遭受到恶意的攻击,例如变成如下操作。
select * from user where username='老李' or '1'='1' and password=";
由此及产生了SQL注入的问题。
2.Preparement
PreparedStatement 解决SQL注入原理,运行在SQL中参数以?占位符的方式表示
select * from user where username = ? and password = ? ;
将带有?的SQL 发送给数据库完成编译(不能执行的SQL 带有?的SQL 进行编译 叫做预编译),在SQL编译后发现缺少两个参数
PreparedStatement 可以将? 代替参数发送给数据库服务器,因为SQL已经编译过,参数中特殊字符不会当做特殊字符编译,无法达到SQL注入的目的主要是采取预编译
3.Demo演示
1 public User findUserByUserNameAndPassword(String username, String password) { 2 3 String sql = "select * from user where username=? and password=?"; 4 5 Connection con = null; 6 PreparedStatement pst = null; 7 ResultSet rs = null; 8 try { 9 // 1.得到连接对象 10 con = JdbcUtils.getConnection(); 11 12 // 2.获取操作sql语句对象 13 pst = con.prepareStatement(sql); // 将sql语句进行预加载. 14 15 // 需要对占位符进行传参数 16 pst.setString(1, username); 17 pst.setString(2, password); 18 19 // 3.操作sql语句 20 rs = pst.executeQuery();// 注意无参数 21 22 // 4.操作结果集 23 if (rs.next()) { 24 User user = new User(); 25 user.setId(rs.getInt("id")); 26 user.setUsername(rs.getString("username")); 27 user.setPassword(rs.getString("password")); 28 return user; 29 } 30 } catch (ClassNotFoundException e) { 31 e.printStackTrace(); 32 } catch (SQLException e) { 33 e.printStackTrace(); 34 } 35 36 return null; 37 }
4.批处理操作
另外PreparementStatement还支持批量SQL语句的操作,有兴趣的可以查一下相关的API,主要方法如下
addBatch(); 添加sql到批处理
executeBatch();执行批处理
5.Demo演示
1 public class PreparedStatementBatchTest { 2 3 public static void main(String[] args) throws ClassNotFoundException, 4 SQLException { 5 6 String sql = "insert into user values(?,?)"; 7 // 1.得到Connection 8 Connection con = JdbcUtils.getConnection(); 9 10 // 2.得到PreparedStatement 对象 11 PreparedStatement pst = con.prepareStatement(sql); 12 13 // 3.执行批处理 14 long l1=System.currentTimeMillis(); 15 for (int i = 1; i <= 10000; i++) { 16 17 pst.setInt(1, i); 18 pst.setString(2, "name" + i); 19 20 pst.addBatch(); //添加批处理 21 22 if(i%1000==0){ 23 pst.executeBatch(); 24 pst.clearBatch(); //清空批处理语句. 25 } 26 } 27 28 System.out.println(System.currentTimeMillis()-l1); 29 30 pst.executeBatch(); 31 32 //4.关闭资源 33 pst.close(); 34 con.close(); 35 }