PreparedStatement接口介绍
PreparedStatement
是Statement
接口的子接口,继承于父接口中所有的方法.它是一个预编译的SQL语句对象- 预编译: 是指SQL语句被预编译,并存储在
PreparedStatement
对象中. 然后可以使用此对象多次市郊地执行该语句
PreparedStatement特点
- 因为有预先编译的功能, 提高SQL的执行效率
- 可以有效的防止SQL注入的问题,安全性更高
获取PreparedStatement对象
与Statement
类似, 都是通过Connection
进行创建创建
Connection接口中的方法 | 说明 |
---|---|
PreparedStatement prepareStatement(String sql) | 指定预编译的SQL语句 |
- 预编译的SQL语句: SQL语句中使用占位符?
PreparedStatement接口常用方法
- 与
Statement
类似,接口常用方法名都是int executeUpdate()
与ResultSet executeQuery
- 与
Statement
不同,上述两个方法是没有参数的.因为在构造PrepareStatement
对象时,就已经传入SQL进行了预编译
常用方法 | 说明 |
---|---|
int executeUpdate() | 执行insert / update / delete 语句.返回受影响的行数 |
ResultSet executeQuery() | 执行select语名.返回结果集对象Result |
使用PreparedStatement的步骤
- 编定SQL语句,未知内容使用 ? 占位
select * from test_02 where name = ? and password = ?
- 获取
PreparedStatement
对象 - 设置实际参数: 调用
setXxx
方法 - 执行参数化SQL
- 关闭资源
使用PreparedStatement完成登录案例
代码示例
public class LoginTest02 {
public static void main(String[] args) throws SQLException {
// 1.获取连接
Connection conn = JDBCUtils.getConnection();
// 2.使用占位符创建sql语句,获取prepareStatement对象
// 使用?占位符的方式来设置参数
String sql = "select * from test_02 where name = ? and password = ?";
PreparedStatement preparedStatement = conn.prepareStatement(sql);
// 3.提示用户输入用户名和密码
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String user = sc.next();
System.out.println("请输入密码:");
String pass = sc.next();
// 4.替换占位符,执行sql语句
// 设置参数,使用setXXX(int 占位符位置 从1开始, 要设置/替换的值)的方法设置占位符的参数
preparedStatement.setString(1,user); // 设置第一个问号值为name
preparedStatement.setString(2,pass);
ResultSet resultSet = preparedStatement.executeQuery();
// 5.处理结果集,判断是否登录成功
if(resultSet.next()){
System.out.println("登录成功!欢迎:" + user);
}else{
System.out.println("登录失败!");
}
// 6.关闭对象
JDBCUtils.close(conn,preparedStatement,resultSet);
}
}
运行结果(正常)
运行结果(SQL注入)
这里提示登录失败,也就是SQL注入的方式没有成功.
原因是: 刚刚我们使用了?作为占位符,那么在输入密码时,无论输入什么,其实都会整体以String形式赋值给sql语句.
所以这里最终的sql语句其实是select * from test_02 where name = 'wdm' and password = "'0704' or '1' = '1' "
. 很明显, 这个就不会返回正常结果
PreparedStatement的执行原理
Statement与PrepareStatement的区别
Statement
用于执行静态SQL语句,在执行时,必须指定一个事先准备好的SQL语句PreparedStatement
是预编译的SQL语句对象,语句中可以包含动态参数"?", 在执行时可以为"?"动态设置参数值PreparedStatement
可以减少编译次数提高数据库性能
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。