文章目录
- 获取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();---执行selectpstmt.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接口中的方法执行sqlResultSet 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接口中的方法执行sqlResultSet 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' --