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);
}
}