SQL注入的问题&使用PreparedStatement对象防止SQL注入

1.SQL注入的问题:sql存在漏洞,会被攻击导致数据泄露

SQL注入是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
在拼接SQL时,有一些sql的特殊关键字参与字符串的拼接,会造成一些安全性的问题

package cn.company.jdbc;

import cn.company.jdbc.utils.JdbcUtils;

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

public class SQL注入 {
    public static void main(String[] args) throws SQLException {
        login("kuangshen", "123456");  // 正常传参
        System.out.println("===========");
        login(" 'or '1=1", "123456");  // SQL注入,把所有的信息都盗取出来
    }

    // 登录业务
    public static void login(String username, String password) throws SQLException {
        Connection connection = null;
        Statement statement = null;
        ResultSet rs = null;
        try {
            connection = JdbcUtils.getConnection();
            statement = connection.createStatement();
            String sql = "select * from users where `name`='"+username+"'AND `password` ='"+password+"'";
            rs = statement.executeQuery(sql);
            while (rs.next()) {
                System.out.println(rs.getObject("name"));
                System.out.println(rs.getObject("password"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.releaseConnection(connection, statement, rs);
        }
    }
}

 

 可以看到SQL注入能够把所有的信息盗取出来。

2.解决SQL注入问题

后期都会使用PreparedStatement来完成增删改查的所有操作

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

PreparedStatement防止SQL注入的本质,把传递进来的参数当做字符,假设其中存在转义字符,就直接忽略,比如说 会被直接转义

预编译SQL,参数使用?作为占位符,需要在执行SQL的时候,给?赋值

静态的SQL,之前的Statement用于执行静态SQL语句,所谓静态的,就是SQL语句是字符串拼接的方式,

步骤:

(1)导入驱动jar包

(2)注册驱动(让程序知道是哪个驱动包)

(3)获取数据库链接对象Connection

(4)定义sql

注意:SQL的参数使用?作为占位符,如:select * from user where username=? and password=?;

(5)获取执行sql语句的对象,PreparedSatement  Connection.prepareStatement(String sql)

(6)给?赋值:

  方法:使用setXxx(参数1,参数2),参数1表示?的位置编号,从1开始;参数2表示?的值

(7)执行sql,接受返回结果,不需要传递SQL语句

(7)处理结果

(8)释放资源

新增:

package cn.company.jdbc;

import cn.company.jdbc.utils.JdbcUtils;

import java.sql.Connection;
import java.util.Date;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TestPreparedStatement {
    public static void main(String[] args) throws SQLException {
        Connection conn = null;
        PreparedStatement statement = null;
        try {
            conn = JdbcUtils.getConnection();
            // 使用占位符?代替参数
            String sql = "INSERT INTO users values(?,?,?,?,?)";
            statement = conn.prepareStatement(sql);

            // 手动给参数赋值
            statement.setString(1, String.valueOf(4));
            statement.setString(2, "qijiang");
            statement.setString(3, "123456");
            statement.setString(4,"243555777@qq.com" );
            // 注意点:sql.Date 数据库用的
            //        util.Date java用的  new Date().getTime()获取当前时间戳
            statement.setDate(5, new java.sql.Date(new Date().getTime()));

            // 执行sql
            int i = statement.executeUpdate();
            if (i > 0) {
                System.out.println("插入成功!");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.releaseConnection(conn, statement, null);
        }
    }
}

  

 删除

package cn.company.jdbc;

import cn.company.jdbc.utils.JdbcUtils;

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

public class TestPreparedStatementDelete {
    public static void main(String[] args) throws SQLException {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            connection = JdbcUtils.getConnection();
            String sql = "delete from users where id=?";
            // 预编译
            preparedStatement = connection.prepareStatement(sql);
            // 手动赋值
            preparedStatement.setInt(1, 4);  // id=4
            // 执行sql
            int i = preparedStatement.executeUpdate();
            if (i > 0) {
                System.out.println("删除成功!");
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.releaseConnection(connection, preparedStatement, null);
        }
    }
}

  更新

package cn.company.jdbc;

import cn.company.jdbc.utils.JdbcUtils;

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

public class TestPreparedStatementUpdate {
    public static void main(String[] args) throws SQLException {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            connection = JdbcUtils.getConnection();
            String sql = "update users set name=? where id=?";
            // 预编译sql
            preparedStatement = connection.prepareStatement(sql);

            // 手动给参数赋值
            preparedStatement.setString(1, "Gump Yan");
            preparedStatement.setString(2, "3");

            // 执行sql
            int i = preparedStatement.executeUpdate();
            if (i > 0) {
                System.out.println("修改成功!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.releaseConnection(connection, preparedStatement, null);
        }
    }
}

  

 查询

package cn.company.jdbc;

import cn.company.jdbc.utils.JdbcUtils;

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

public class TestPreparedStatementQuery {
    public static void main(String[] args) throws SQLException {
        login("lisi", "123456");
        // login(" 'or '1=1","123456");  // SQL注入
    }

    private static void login(String username, String password) throws SQLException {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet rs = null;
        try {
            connection = JdbcUtils.getConnection();
            String sql = "select * from users where `name`=? and `password`=?";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1, username);
            preparedStatement.setString(2, password);
            rs = preparedStatement.executeQuery();
            while (rs.next()) {
                System.out.println(rs.getObject("name"));
                System.out.println(rs.getObject("password"));
                System.out.println("===============");
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.releaseConnection(connection, preparedStatement, rs);
        }
    }
}

  

原文地址:https://www.cnblogs.com/GumpYan/p/14069516.html