Statement和PreparedStatement不再陌生

上文jdbc不再是个谜中提到执行SQL语句的传输器类型Statement,其实该对象存在安全性问题,即“SQL注入问题”,防止SQL注入有很多方法,但是作为Statement类型的子对象——PreparedStatement类型的对象也是为了解决这个问题,这也是两个类型对象的区别,下面我们了解下。
Statement类型对象的使用
参考上篇jdbc不再是个谜
上述代码中存在一些问题:
在这里插入图片描述
用户名为:张三’ #
密码为:(空)
拼接后的SQL语句:

select * from user where username='张三'# ' and password=''

最终不用密码即可登录!

产生问题的原因是因为该SQL语句是字符串拼接而成的,这种方法传递的参数中如果带有“#、‘、–”等字符时,则会修改原来的SQL语句,从而达到非法获取数据的目的。

PreparedStatement类型的对象

package com.hopeful.jdbc;

import netscape.security.UserTarget;

import java.sql.*;
import java.util.Scanner;

public class LoginUser {
    
    
    static Connection connection = null;
    static PreparedStatement ps = null;
    static ResultSet rs = null;
    public static void main(String[] args) {
    
    

        try {
    
    
            // 获取连接
            connection = Jutils.getConnection();

            System.out.println("请登录");
            System.out.println("请输入用户名");
            Scanner scanner = new Scanner(System.in);
            String user = scanner.nextLine();
            System.out.println("请输入密码");
            String password = scanner.nextLine();
            loginUserByPreparStatement(user, password);

        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        } finally {
    
    
            Jutils.releaseResource(rs, ps, connection);
        }
    }

    private static void loginUserByPreparStatement(String user, String password) {
    
    
        String sql = "select * from user where username = ? and password = ?";
        try {
    
    
            ps = connection.prepareStatement(sql);
            ps.setString(1, user);
            ps.setString(2, password);
            ResultSet resultSet = ps.executeQuery();
            if(resultSet.next())  {
    
    
                System.out.println("登录成功");
            }else {
    
    
                System.out.println("登录失败");
            }
        } catch (SQLException throwables) {
    
    
            throwables.printStackTrace();
        }
    }
}

在这里插入图片描述
用户名为:张三’ #
密码为:(空)
最终用户名和密码不正确无法登录!

该对象可以防止SQL注入的原因是,先把SQL语句模板发送到服务器,经编译后,SQL语句结构不会再发生变化,随后传递参数时,即使参数中包含SQL关键字或特殊字符(#、–、’)时,也只能作为普通文本进行处理,故不存在安全问题。

当然也可以使用正则表达式防止SQL攻击,当遇到SQL关键字或特殊字符时,提示非法输入而不进行参数传递,这里暂且提供思路。

该文如对你有用,请支持下哦!你的支持(收藏、点赞和关注)将是我写作的最大动力。

Guess you like

Origin blog.csdn.net/weixin_47088026/article/details/113748400