前言
https://blog.csdn.net/weixin_45417821/article/details/128536812
缺陷
1,静态查询
2,可能发生注入攻击,动态值充当了SQL语句结构,影响了原有的查询结果!
代码展示
import java.sql.*;
import java.util.Scanner;
/**
* @author : Aurora
* @Date : 2023/1/4
* @Describe : 使用预编译statement完成用户登录
*
* TODO 防止注入攻击 | 演示PS的使用流程
*/
public class PSUserLoginPart {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
//1.获取用户信息
Scanner scanner = new Scanner(System.in);
System.out.println("请输入账号");
String account = scanner.nextLine();
System.out.println("请输入密码");
String password = scanner.nextLine();
//2.数据库流程
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
String url = "jdbc:mysql://localhost:13306/huan";
String user = "root";
String pass = "123456";
Connection connection = DriverManager.getConnection(url, user, pass);
/**
* preparedStatement
* 1.编写SQL语句结果,不包含动态值部分的语句,动态值部分使用占位符 ? 替代, 注意:? 只能代替动态值
* 2.创建preparedStatement,并且传入动态值
* 3.动态值 占位符 赋值 ? 单独赋值即可
* 4.发送SQL语句即可,并获取返回结果
*/
//编写SQL语句
String sql = "select * from t_user where account = ? and password = ?";
//创建预编译并且设置SQL语句结果
PreparedStatement preparedStatement = connection.prepareStatement(sql);
/**
* 单独的占位符进行赋值
* 参数1,index 占位符的位置 从左向右数 从1 开始 账号 ? 1
* 参数2,object 占位符的值 可以是设置任意类型的数据,避免了我们拼接和类型更加丰富!
*
*/
preparedStatement.setObject(1,account);
preparedStatement.setObject(2,password);
//发送sql语句,并获取返回结果!
//preparedStatement.executeUpdate() | executeQuery();
ResultSet resultSet = preparedStatement.executeQuery();
//结果集解析
if (resultSet.next()){
System.out.println("登录成功!");
}else {
System.out.println("登录失败!");
}
}
}