#JDBC_演示SQL注入现象(解决SQL注入现象)

#JDBC_演示SQL注入现象(解决SQL注入现象)

package com.snailxq.jdbc;

import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
 *解决SQL注入现象:
 *    只要用户提供的信息不参与SQL语句的编译过程,问题就解决了
 *    即使用户提供的信息中含有SQL语句的关键字,单没有参与编译,不起作用。
 *    要想用户的信息不参与SQL的编译,必须使用java.sql.PreparedStatement
 *    PreparedStatement继承了java.sql.Statement接口
 *    PreparedStatement是属于预编译的数据库操作对象。
 *    PareparedStatement原理:预先对SQL语句的框架进行编译,然后给SQL语句传“值”。
 *对比一下Statement和PreparedStatement?
 *   -Statement存在SQL注入现象,PreparedStatement解决了SQL注入现象。
 *   -Statement是编译一次执行一次,PreparedStatement编译一次,执行N次。
 *   -PreparedStatement在编译阶段做安全检查。
 * PreparedStatement使用较多,只有极少数情况下使用Statement
 * 什么情况下使用Statement?
 * 业务方面使用SQL注入的时候。如:按照价格排序,销量。
 */


public class JDBCTest07 {

    public static void main(String[] args) {
        //初始化一个界面
        Map<String,String> userLoginInfo = initUI();
        //验证用户名和密码
        boolean loginSuccess = login(userLoginInfo);
        //输出结果
        System.out.println(loginSuccess ? "登录成功":"登录失败");


    }

    /**
     * 用户登录
     * @param userLoginInfo 用户登录信息
     * @return
     */
    private static boolean login(Map<String, String> userLoginInfo) {
        // 打标记
        boolean loginSussess =false;
        //单独定义变量
        String loginName =userLoginInfo.get("loginName");
        String loginPwd =userLoginInfo.get("loginPwd");

        Connection connection =null;
        PreparedStatement preparedStatement= null;  //这里使用PreparedStatement(预编译的数据库操作对象)
        ResultSet resultSet = null;
        try {
            //1.注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/everours","root","333");
            //3.获取预编译数据库连接对象
            //SQL语句的框架,一个?表示一个占位符,一个?将来接受一个“值”,注意占位符不能用单引号括起来。
            String sql ="select * from t_user where loginName= ? and  loginPwd = ? ";
            //程序执行到此处的时候,会发送SQL语句的框子给DBMS,然后DBMS进行SQL语句的预先编译
            preparedStatement =connection.prepareStatement(sql);
            //给占位符?传值。(第一个问号是下标是1,第二个问号下标是2,JDBC所有的下标从1开始)
            preparedStatement.setString(1,loginName);
            preparedStatement.setString(2,loginPwd);

            //4.执行SQL


            resultSet =preparedStatement.executeQuery();
            //5.处理结果集
            if (resultSet.next()){
                loginSussess=true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //6.释放结果集
            if (resultSet !=null){
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }if (preparedStatement !=null){
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }if (connection !=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return  loginSussess;
    }

    private static Map<String, String> initUI() {
        Scanner s= new Scanner(System.in);

        System.out.print("用户名:");
        String loginName=s.nextLine();

        System.out.print("密码:");
        String  loginPwd=s.nextLine();

        Map<String,String> userLoginInfo =new HashMap<>();
        userLoginInfo.put("loginName",loginName);
        userLoginInfo.put("loginPwd",loginPwd);

        return userLoginInfo;

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值