一、它是Statement接口的子接口;
二、好处:
- 防SQL攻击;
- 提高代码的可读性、可维护性;
- 提高效率!
//SQL攻击:
//login()方法中有如下语句: String sql = "SELECT * FROM user WHERE " +"username='" + username + "' and password='" + password + "'";
//调用login方法 login("a' or 'a'='a", "a' or 'a'='a"); //组合起来的sql语句为: SELECT * FROM tab_user WHERE username='a' or 'a'='a' and password='a' or 'a'='a' //总返回true
三、PreparedStatement的用法:
1、给出SQL模板!
2、调用Connection的PreparedStatement prepareStatement(String sql模板);
3、调用pstmt的setXxx()系列方法sql模板中的?赋值!
4、调用pstmt的executeUpdate()或executeQuery(),但它的方法都没有参数。
/* * 一、得到PreparedStatement * 1. 给出sql模板:所有的参数使用?来替代 * 2. 调用Connection方法,得到PreparedStatement */ String sql = "select * from t_user where username=? and password=?"; PreparedStatement pstmt = con.prepareStatement(sql); /* * 二、为参数赋值 */ pstmt.setString(1, username);//给第1个问号赋值,值为username pstmt.setString(2, password);//给第2个问号赋值,值为password ResultSet rs = pstmt.executeQuery();//调用查询方法,向数据库发送查询语句 pstmt.setString(1, "liSi"); pstmt.setString(2, "123"); pstmt.executeQuery();
预处理的原理
- 服务器的工作:
1、校验sql语句的语法!
2、编译:一个与函数相似的东西!
3、执行:调用函数
- PreparedStatement:
前提:连接的数据库必须支持预处理!几乎没有不支持的!
每个pstmt都与一个sql模板绑定在一起,先把sql模板给数据库,数据库先进行校验,再进行编译。执行时只是把参数传递过去而已!
若二次执行时,就不用再次校验语法,也不用再次编译!直接执行!