package cn.taylor.demo4; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import org.junit.Test; /* * 为了避免sql攻击,学习PreparedStatement的用法 */ public class Demo4 { /* * 如何得到PreparedStatement对象 * > 给出SQL模板 * > 调用Connection的preparedStatement(String sql模板)方法生成pstmt * > 调用pstmt的setXXX()系列方法sql模板中的?赋值 * > 调用psmt的excuteUpdate()或excuteQuery(),但它的方法都没有参数。 * */ public boolean login2(String uname,String upass) throws Exception{ String driverClassName="com.mysql.jdbc.Driver"; String url="jdbc:mysql://localhost:3306/taylor"; String username="root"; String password="123456"; Class.forName(driverClassName); Connection con=DriverManager.getConnection(url,username,password); //得到模板和pstmt String sql="select * from user where username=? and password=?"; PreparedStatement pstmt=con.prepareStatement(sql); //为参数赋值 pstmt.setString(1, uname); //给第一个参数赋值,值为uname pstmt.setString(2, upass); ResultSet rs=pstmt.executeQuery(); //调用查询方法 return rs.next(); } @Test public void fun2() throws Exception{ String uname="zhangsan"; String upass="123456"; // String uname="a' or 'a'='a"; //在这里sql攻击就失效了 // String upass="a' or 'a'='a"; boolean bool=login2(uname,upass); System.out.println(bool); } /*预处理的原理 * > 服务器的工作: * 1.检查sql语句。 * 2.编译:一个与函数相似的东西 * 3.执行:调用函数 */ /*PreparedStatement * > 介绍:PreparedStatemrnt是Statement接口的子接口; * 强大之处:防Sql攻击 * 提高代码的可读性,可维护性 * 提高效率 * > 前提:连接的数据库必须支持预处理。基本上都是支持的 * > 每个pstmt都与一个sql模板绑定在一起,先把sql模板给数据库,数据库先 * 进行校验,在进行编译,最后执行时只是将参数传递过去而已。 * > 若第二次执行时,就不用再次检验语法和编译了,而是直接执行。 */ }
package cn.taylor.demo5; import java.sql.Connection; import java.sql.PreparedStatement; import org.junit.Test; public class Demo7 { @Test public void fun() throws Exception{ Connection con=JdbcUtils.getConnection(); String sql="INSERT INTO tab_stu VALUES(?,?)"; PreparedStatement pstmt =con.prepareStatement(sql); //疯狂的添加参数 //long start =System.currentTimeMillis(); for(int i=0;i<1000;i++){ pstmt.setLong(1, i+1); pstmt.setString(2, i%2==0?"男":"女"); //pstmt.execute(); pstmt.addBatch(); //添加批,这一组参数就保存到了集合中了,相当于装车 } long start =System.currentTimeMillis(); pstmt.executeBatch(); //执行批,相当于发车 /* * 没开批处理的时间是39997毫秒 * 批处理的默认是关闭的,需要在配置文件的url中添加 ?rewriteBatchedStatements=true * 这样的传输时间变成63毫秒,就快了贼多。 */ long end=System.currentTimeMillis(); System.out.println(end-start); } }