文章目录
- 获取PreparedStatement对象
- PreparedStatement是如何解决SQL注入问题的
- PreparedStatement的 应用
- 上述如何解决sql注入的问题呢?
获取PreparedStatement对象
PreparedStatement是Statement的子接口,可以防止sql注入问题。可以通过Connection接口中的prepareStatement(sql)方法获得PreparedStatement的对象。
方法如下所示:
// 创建一个 PreparedStatement 对象来将参数化的 SQL 语句发送到数据库。
PreparedStatement prepareStatement(String sql);
注意:sql提前创建好的。sql语句中需要参数。使用?进行占位。
举例:
select *from user where username='zhangsan' and password = '123456';
使用 ?进行占位
select * from user where username = ? and password = ?;
String sql = ”select * from user where username = ? and password = ?”;
PreparedStatement是如何解决SQL注入问题的
步骤一:**PreparedStatement pstmt = conn.prepareStatement(sql);**
-----需要你事先传递sql。如果sql需要参数,使用?进行占位。
步骤二:设置参数(执行sql之前):pstmt.setXXX(int index, 要放入的值)
-----根据不同类型的数据进行方法的选择。第一个参数 index 表示的是 ?出现的位置。从1开始计数,有几个问号,就需要传递几个参数。
方法的参数说明:
第一个参数:int index ;表示的是问号出现的位置。 问号是从1开始计数
第二个参数:给问号的位置传入的值。
步骤三、执行,不需要在传递sql了。
pstmt.executeQuery();—执行select
pstmt.executeUpdate();—执行insert,delete,update
小结:
1.使用预编译接口PreparedStatement 好处:
1.解决sql注入问题
2.提供效率,对sql语句只会预编译一次
2.使用编译接口PreparedStatement步骤:
1)使用连接对象调用方法获取预编译接口对象:PreparedStatement pstmt = conn.prepareStatement(sql);
2)给sql语句占位符赋值:pstmt.setXxx(第几个占位符,实际值)
3)运行sql语句:
pstmt.executeQuery();---执行select
pstmt.executeUpdate();---执行insert,delete,update
PreparedStatement的 应用
import java.sql.*;
import java.util.Scanner;
public class JDBCTest06 {
public static void main(String[] args) throws Exception {
/*
使用PreparedStatement接口解决sql注入问题
1.使用Connection接口对象调用方法,获取PreparedStatement预编译接口
PreparedStatement prepareStatement(String sql)
2.使用预编译接口 PreparedStatement的对象调用PreparedStatement接口中的方法给sql语句中的占位符赋值
setXxx(第几个占位符,实际值)
3.使用预编译接口 PreparedStatement对象调用PreparedStatement接口中的方法执行sql
ResultSet executeQuery() 执行DQL(查询语句)
int executeUpdate() 执行DML(增删改语句)
*/
//1.创建键盘录入对象
Scanner sc = new Scanner(System.in);
//2.提示输入用户名和密码
System.out.println("-------请输入用户名:-------");
//获取用户名
String inputUsername = sc.nextLine();
System.out.println("-------请输入密码:-------");
//获取密码
String inputPassword = sc.nextLine();
//3.获取数据
//4.注册驱动
//5.获取和数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day03_heima139", "root", "1234");
//6.使用Connection接口对象调用方法,获取PreparedStatement预编译接口
// PreparedStatement prepareStatement(String sql)
String sql = "select * from user3 where username=? and password=?";
PreparedStatement pst = conn.prepareStatement(sql);
//2.使用预编译接口 PreparedStatement的对象调用PreparedStatement接口中的方法给sql语句中的占位符赋值
//setXxx(第几个占位符,实际值)
//第一个参数1表示上述sql语句中的第一个占位符(?)位置
//inputUsername :表示给第一个占位符赋的实际值
// zhangsan\'\ \-\-
pst.setString(1,inputUsername);
//第一个参数2表示上述sql语句中的第二个占位符(?)位置
//inputPassword :表示给第二个占位符赋的实际值
pst.setString(2,inputPassword);
/*
3.使用预编译接口 PreparedStatement对象调用PreparedStatement接口中的方法执行sql
ResultSet executeQuery() 执行DQL(查询语句)
*/
ResultSet rs = pst.executeQuery();
//8.处理结果集
//用户名唯一,查询的是一条数据,所以这里使用if即可
if(rs.next()){
//rs.next() :如果当前指针指向的行有数据则返回true
//获取用户名
String username = rs.getString("username");
//输出
System.out.println("恭喜您,亲,登录成功,欢迎光临我的小店,你的用户名是"+username);
}else{
System.out.println("用户名或者密码错误");
}
//9.释放资源
rs.close();
pst.close();
conn.close();
}
}
上述如何解决sql注入的问题呢?
在方法 setXxx()
内部解决的。
例如上述 st.setString(1,inputUsername);
,将输入的用户名 "zhangsan' -- "
传入给setString方法体中,在该方法体中使用转义符号 / ,将特殊符号给转义了,转义之后再发送给 mysql 服务器,那么特殊符号例如–就不是注释的意思就是普通字符,mysql 会认为用户名的值是:zhangsan' --