PreparedStatement对象详解(推荐使用)==>防止SQL注入,并且效率更高

PreparedStatement 可以防止SQL注入,并且效率更高。

测试插入

示例:

package jdbc.lesson;

import jdbc.lesson.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestInsert {
    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;

        try {
            connection = JdbcUtils.getConnection();// 获取数据库连接
            statement = connection.createStatement(); // 获得SQL执行对象
            String sql = "INSERT INTO `users`(`id`,`NAME`,`PASSWORD`,`email`,`birthday`)\n" +
                    "VALUES(4,'周天天','123456','[email protected]','2000-12-04');";

            int i = statement.executeUpdate(sql);
            if (i > 0) {
                System.out.println("插入数据成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, statement, resultSet);
        }
    }
}

结果:
在这里插入图片描述

在这里插入图片描述


测试查询

示例:

package jdbc.lesson.utils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestQuery {
    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connection = JdbcUtils.getConnection();
            String sql = "SELECT * FROM `users` WHERE `id` = ?;";
            preparedStatement = connection.prepareStatement(sql);

            preparedStatement.setInt(1, 1);

            // 执行
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                System.out.println("id = " + resultSet.getObject("id"));
                System.out.println("NAME = " + resultSet.getObject("NAME"));
                System.out.println("PASSWORD = " + resultSet.getObject("PASSWORD"));
                System.out.println("email = " + resultSet.getObject("email"));
                System.out.println("birthday = " + resultSet.getObject("birthday"));
                System.out.println("");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, preparedStatement, resultSet);
        }

    }
}

结果:
在这里插入图片描述


防止SQL注入

1. 正常登录

package jdbc.lesson;

import jdbc.lesson.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

// SQL注入问题
public class SQLInjection02 {
    public static void main(String[] args) {
        login("周天天", "123456");// 正常登录
        //login("'or ' 1=1", "'or' 1=1");// 异常登录
    }

    // 登录业务
    public static void login(String username, String password) {
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;

        try {
            connection = JdbcUtils.getConnection();// 获取数据库连接
            String sql = "SELECT * FROM `users` WHERE `NAME`= ?  AND `PASSWORD`= ?;";
            statement = connection.prepareStatement(sql); // 获得SQL执行对象

            statement.setObject(1, username);
            statement.setObject(2, password);
            resultSet = statement.executeQuery();

            while (resultSet.next()) {
                System.out.println("name = " + resultSet.getObject("name"));
                System.out.println("password = " + resultSet.getObject("password"));
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, statement, resultSet);
        }
    }
}

结果:
在这里插入图片描述


2. 异常登录(这里并不会返回所有结果)
如需对比请看 SQL注入问题

package jdbc.lesson;

import jdbc.lesson.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

// SQL注入问题
public class SQLInjection02 {
    public static void main(String[] args) {
        // login("周天天", "123456");// 正常登录
        login("'or ' 1=1", "'or' 1=1");// 异常登录
    }

    // 登录业务
    public static void login(String username, String password) {
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;

        try {
            connection = JdbcUtils.getConnection();// 获取数据库连接
            String sql = "SELECT * FROM `users` WHERE `NAME`= ?  AND `PASSWORD`= ?;";
            statement = connection.prepareStatement(sql); // 获得SQL执行对象

            statement.setObject(1, username);
            statement.setObject(2, password);
            resultSet = statement.executeQuery();

            while (resultSet.next()) {
                System.out.println("name = " + resultSet.getObject("name"));
                System.out.println("password = " + resultSet.getObject("password"));
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, statement, resultSet);
        }
    }
}

结果:
在这里插入图片描述

总结

PreparedStatement防止Sql注入的本质是把传递进来的参数当作字符
假设其中存在转义字符,直接忽略,’ 会被直接转移

猜你喜欢

转载自blog.csdn.net/I_r_o_n_M_a_n/article/details/114375916