PreparedStatement的使用和批处理

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

}


猜你喜欢

转载自blog.csdn.net/roseTaylor/article/details/80290102