JDBC_08_解决SQL注入问题 (登录和注册)

解决SQL注入问题

  • 只要用户提供的信息不参与sql语句的编译过程,那么尽管用户输入的信息中含有sql关键字那么也不会起作用了

  • 要想使用户提供信息不参与sql语句的编译过程,那么必须使用 java.sql.PreparedStatement 预编译的数据库操作对象,提前编译sql语句框架

  • PreparedStatement 继承了 Statement

  • PreparedStatement的原理是预先对sql语句框架进行编译,然后再给sql语句传值。

  • 将Statement(数据库操作对象) 换为 PreparedStatement(预编译的数据库操作对象)

  • 获取预编译数据库连接对象preparedStatement,将sql语句框架预先进行编译。 其中SQL语句中的 一个 ?表示一个占位符,占位符不能用单引号括起来。

    • preparedStatement=connection.prepareStatement("select * from t_user where loginName=? and loginPwd=? "); 使用 ?进行占位。
  • 给占位符 ? 传值 注意:第一个问号的下标是1 ,第二个问号下标是 2

      - preparedStatement.setString(1,loginName);   第一个问号传   loginName
    
      - preparedStatement.setString(2,loginPwd);    第二个问号传   loginPwd
    
  • 代码实例:

           
    
         import java.sql.*;
         import java.util.HashMap;
         import java.util.Map;
         import java.util.Scanner;
    
         /**
          * 解决sql注入问题
          * 只要用户提供的信息不参与sql语句的编译过程,那么尽管用户输入的信息中含有sql关键字那么也不会起作用了
          * 要想使用户提供信息不参与sql语句的编译过程,那么必须使用java.sql. PreparedStatement   预编译的数据库操作对象
          * PreparedStatement 继承了 Statement
          * PreparedStatement的原理是预先对sql语句框架进行编译,然后再给sql语句传值
          * 将Statement(数据库操作对象) 换为  PreparedStatement(预编译的数据库操作对象)
          *
          *
          */
    
         public class 解决sql注入 {
             public static void main(String[] args) throws SQLException {
    
                 //掉用initUI()获取用户名密码
                 Map<String,String> userLoginInfo=initUI();
    
                 //调用register()方法。
                 //boolean registerSuccess=register(userLoginInfo);
    
                 //输出结果
                 //System.out.println(registerSuccess?"注册成功":"注册失败");
    
                 //调用logIn()方法。
                 boolean loginSuccess=login(userLoginInfo);
                 System.out.println(loginSuccess?"登陆成功":"密码错误");
    
    
             }
    
    
    
             /**
              * 用户注册
              * @param userLoginInfo  用户登录信息
              * @return true成功, false失败
              */
    
             private static boolean register(Map<String, String> userLoginInfo) {
                 //创建连接对象
                 Connection connection=null;
                 Statement statement=null;
                 int count=0;
    
                 try {
                     //注册驱动
                     Class.forName("com.mysql.cj.jdbc.Driver");
    
                     //获取连接
                     connection= DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai",
                             "root","123456");
    
                     //获取数据库操作对象
                     statement=connection.createStatement();
    
                     //执行SQL语句
                     count=statement.executeUpdate("insert into t_user(loginName,loginPwd,realName)values('"+userLoginInfo.get("loginName")+"','"+userLoginInfo.get("loginPwd")+"',' ') ");
    
                 } catch (ClassNotFoundException | SQLException e) {
                     e.printStackTrace();
                 }finally {
                     if(statement!=null){
                         try {
                             statement.close();
                         } catch (SQLException e) {
                             e.printStackTrace();
                         }
                     }
    
                     if(connection!=null){
                         try {
                             connection.close();
                         } catch (SQLException e) {
                             e.printStackTrace();
                         }
                     }
                 }
                 if(count==1){
                     return true;
                 }
                 return  false;
             }
    
    
             /**
              * 用户登录
              * @param userLoginInfo 用户信息
              * @return 成功true 失败fslse
              */
    
             private static boolean login(Map<String, String> userLoginInfo) throws SQLException {
    
                 //标识
                 boolean flag=false;
    
                 //获取用户信息
                 String loginName=userLoginInfo.get("loginName");
                 String loginPwd=userLoginInfo.get("loginPwd");
    
                 //创建连接对象
                 Connection connection=null;
                 PreparedStatement preparedStatement=null;        //这里使用PreparedStatement(预编译的数据库操作对象)
                 ResultSet resultSet=null;
    
                 try {
                     //注册驱动
                     Class.forName("com.mysql.cj.jdbc.Driver");
    
                     //获取连接
                     connection=DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai",
                             "root","123456");
    
                     //获取预编译数据库连接对象,将sql语句框架预先进行编译。其中一个?表示一个占位符,占位符不能用单引号括起来
                     preparedStatement=connection.prepareStatement("select * from t_user where loginName=? and loginPwd=?"); //使用?进行占位
    
                     //给占位符? 传值 注意:第一个问号的下标是1 ,第二个问号下标是 2
                     preparedStatement.setString(1,loginName); //第一个问号传 loginName
                     preparedStatement.setString(2,loginPwd); //第二个问号传 loginPwd
    
    
                     //执行SQL语句  使用 PreparedStatement,执行sql的使用,不用再传入sql语句,因为前面已经编译过了。
                     resultSet=preparedStatement.executeQuery();
    
                     //处理查询结果集
                     if(resultSet.next()){
                         flag=true;
                     }
                 } catch (ClassNotFoundException | SQLException e) {
                     e.printStackTrace();
                 }finally {
                     if(resultSet!=null){
                         resultSet.close();
                     }
                     if(preparedStatement!=null){
                         preparedStatement.close();
                     }
                     if (connection!=null){
                         connection.close();
                     }
                 }
    
                 return  flag;
             }
    
             /**
              * 初始化用户界面
              * @return 返回用户登录信息
              */
             private static Map<String, String> initUI() {
    
                 //创建用户信息接收对象
                 Scanner scanner=new Scanner(System.in);
                 System.out.println("请输入您的用户名:");
                 String userName=scanner.nextLine();
    
                 System.out.println("请输入您的密码:");
                 String pwd=scanner.nextLine();
    
                 //创建一个Map集合用来存放用户输入得用户名和密码
                 Map<String,String> userLoginInfo=new HashMap<String,String>();
                 userLoginInfo.put("loginName",userName);
                 userLoginInfo.put("loginPwd",pwd);
                 return userLoginInfo;
             }
         }
    
posted @ 2021-04-17 10:21  失昼  阅读(188)  评论(0)    收藏  举报