1. 问题介绍用户输入的数据中有SQL关键字或者语法并且这些内容参与了SQL语句的编译导致SQL语句编译后的条件含义为true这种现象就成为SQL注入。预编译SQL注入是一个很经典的问题。 由于编写的SQL语句是在用户输入数据整合后再进行编译的。所以为了避免SQL注入的问题咱们要使SQL语句在用户输入数据前就已经编译完成了完整的SQL语句再进行填充数据。2. PreparedStatementPreparedStatement实现了Statement接口执行SQL语句的方法和最开始使用的Statement对象是一样的。importjava.sql.*;importjava.util.Scanner;/** * 实现注册和登录操作 * 基于SQL注入的问题在这里采用PreparedStatement来解决SQL注入问题。 */publicclassDemo4{publicstaticvoidmain(String[]args)throwsException{// 因为注册驱动的操作做一次就够了他就是将Driver的对象扔到DriverManager的一个List集合中Class.forName(com.mysql.cj.jdbc.Driver);ScannerinputnewScanner(System.in);while(true){// 基于提示做具体什么操作System.out.println(当前可以选择注册或者登录);System.out.println(注册操作输入 1);System.out.println(登录操作输入 2);intiinput.nextInt();// 因为无论是注册还是登录都需要用户输入用户名和密码System.out.println(请输入用户名);Stringusernameinput.next();System.out.println(请输入密码);Stringpasswordinput.next();// 根据i执行不同的逻辑if(i1){// 注册操作//1、获取链接ConnectionconnDriverManager.getConnection(jdbc:mysql://localhost:3306/jdbc_test?characterEncodingUTF-8,root,root);//2、准备注册的insert的SQLStringsqlinsert into user (username,password) values (?,?);//3.1、拿到statementPreparedStatementpsconn.prepareStatement(sql);//3.2 给占位符赋值ps.setString(1,username);ps.setString(2,password);//4、执行SQLintcountps.executeUpdate();//5、根据返回结果基于提示if(count1){System.out.println(注册成功);}//6、释放资源ps.close();conn.close();}else{// 登录操作//1、获取链接ConnectionconnDriverManager.getConnection(jdbc:mysql://localhost:3306/jdbc_test?characterEncodingUTF-8,root,root);//2、准备登录的查询SQLStringsqlselect * from user where username ? and password ?;//3.1、拿到statementPreparedStatementpsconn.prepareStatement(sql);//3.2、给赋值ps.setString(1,username);ps.setString(2,password);//4、执行SQLResultSetresultSetps.executeQuery();if(resultSet.next()){// 到这说明用户名和密码正确登录成功System.out.println(用户名和密码正确登录成功);}else{// 到这说明用户名和密码错误登录失败System.out.println(用户名和密码错误登录失败);}//5、释放资源resultSet.close();ps.close();conn.close();}}}}