PreparedSatement预编译处理对象、解决SQL注入问题

1.1 SQL注入问题

  • SQL攻击的原理:通过 ' 或者是 or 语句去改变SQL的判断条件。
  • JDBC连接mysql数据库实现登录注册功能实际上是存在SQL攻击问题的,别人可以使用任意的用户名以及密码进行登录。

 例如:

用户名:bbb'or' 1=1

密码:sahfsf ' or '1=1

  • 我们让用户输入的密码和SQL语句进行字符串拼接。用户输入的内容作为了SQL语句语法的一部分,改变了原有SQL真正的意义,以上问题称为SQL注入。
  • 要解决SQL注入就不能让用户输入的密码和我们的SQL语句进行简单的字符串拼接。需要使用到PreparedSatement类解决SQL注入。

1.2 PreparedStatement概念

 PreparedStatement预编译对象

PreparedSatement预编译处理对象、解决SQL注入问题_第1张图片

1.3 PreparedStatement作用

  1.  解决SQL注入问题。
  2. 提高了程序的可读性。
  3. 一条SQL语句重复执行多次的时候,可以提高效率。

 1.4 PreparedStatement解决登录SQL注入问题

  • 存在SQL注入问题示例代码演示:
package Utils;

import java.sql.*;
import java.util.Collection;
/*
    工具类
 */
public class JDBCUtils {

    public static final String DIVERCLASS = "com.mysql.jdbc.Driver";
    public  static final String URL = "jdbc:mysql://localhost:3306/test";
    public static  final String USER = "root";
    public static  final String PASSWORD = "root";

    //每次别人获取连接的时候,都需要加载该类。但是一个类只需要加载一次就够了。静态代码块只需要执行一次。
    static {
        try {
            Class.forName(DIVERCLASS);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    //连接
    public static Connection getConnection() {
        Connection connection = null;
        try {
           connection = DriverManager.getConnection(URL,USER,PASSWORD);
            return connection;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }

    //关闭资源
    public static void close(ResultSet rs, Statement  st,Connection conn){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(st!=null){
            try {
                st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
package com.enjoy.test;

import Utils.JDBCUtils;

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

public class LoginTest {
    public static void main(String[] args)throws Exception {
        //创建扫描器
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入账号:");
        String userName = sc.nextLine();
        System.out.println("请输入密码:");
        String password = sc.nextLine();
        boolean flag = login(userName,password);
        if(flag){
            System.out.println("恭喜"+userName+"登录成功");
        }else {
            System.out.println("账号或密码错误或不存在");
        }
    }

    private static boolean login(String userName, String password) throws Exception {
        //获取对象
        Connection connection = JDBCUtils.getConnection();
        //获取SQL运输器
        String sql = "select*from user where name ='"+userName+"' and password='"+password+"'";
        Statement st = connection.createStatement();
        //执行SQL
        ResultSet rs = st.executeQuery(sql);
        return rs.next();
    }
}

  • 改进SQL注入问题示例代码:

 

package com.enjoy.test;

import Utils.JDBCUtils;

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

public class LoginTest {
    public static void main(String[] args)throws Exception {
        //创建扫描器
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入账号:");
        String userName = sc.nextLine();
        System.out.println("请输入密码:");
        String password = sc.nextLine();
        boolean flag = login(userName,password);
        if(flag){
            System.out.println("恭喜"+userName+"登录成功");
        }else {
            System.out.println("账号或密码错误或不存在");
        }
    }

    private static boolean login(String userName, String password) throws Exception {
        //获取对象
        Connection connection = JDBCUtils.getConnection();
        //获取SQL运输器
        String sql = "select*from user where name=? and password=?";
                //得到预编译对象
        PreparedStatement pst = collection.prepareStatement(sql);
        //给?赋值
        pst.setString(1,userName);
        pst.setString(2,password);
        //执行SQL
        ResultSet rs = pst.executeQuery();
        return rs.next();
    }
}

1.5 PreparedStatement运行原理

PreparedSatement预编译处理对象、解决SQL注入问题_第2张图片

 1.6 PreparedStatement实行增删改查

package com.enjoy.test;

import Utils.JDBCUtils;
import org.junit.Test;

import java.sql.*;

/*
    目标:使用preparedstatement实现增删查改
 */
public class Test01 {

    /*
        增加
     */
    @Test
    public void add() throws Exception {
        //获取连接
        Connection connection = JDBCUtils.getConnection();
        //准备SQL语句,得到preparedstatement
        String sql = "insert into student(id,name)values(?,?)";
        PreparedStatement pst = connection.prepareStatement(sql);
        //给?赋值
        pst.setInt(1,01);
        pst.setString(2,"李建");
        //执行SQL语句
       pst.executeUpdate();
        //关闭资源
       JDBCUtils.close(null,pst,connection);
    }
    /*
        删除
     */
    @Test
    public void delete() throws SQLException {
        //获取对象
        Connection connection = JDBCUtils.getConnection();
        //准备SQL语句,获得PreparedStatement
        String sql = "delete from student where id = ?";
        PreparedStatement pst = collection.prepareStatement(sql);
        //设置参数
        pst.setInt(1,1);
        //执行SQL
        pst.executeUpdate();
        //关闭资源
        JDBCUtils.close(null,pst,connection);
    }

    /*
        修改
     */
    @Test
    public void update() throws SQLException {
        //获取连接
        Connection connection = JDBCUtils.getConnection();
        //准备SQL语句,获取PreparedStatement
        String sql = "update  student set name = ? where id=?";
        PreparedStatement pst = connection.prepareStatement(sql);
        //给SQL赋值
        pst.setString(1,"张国荣");
        pst.setInt(2,1);
        //执行SQL
        pst.executeUpdate();
        //关闭资源
        JDBCUtils.close(null,pst,connection);
    }
    /*
        查询
     */
    @Test
    public void query() throws SQLException {
        //获取连接
        Connection connection = JDBCUtils.getConnection();
        //准备SQL语句,获取PreparedStatement
        String sql = "select*from student ";
        PreparedStatement pst = collection.prepareStatement(sql);
        //执行sql
        ResultSet rs = pst.executeQuery();
        while (rs.next()){
            System.out.println("编号:"+rs.getInt("id")+",姓名:"+rs.getString("name"));
        }
        //关闭资源
        JDBCUtils.close(null,pst,connection);

    }
}

 

你可能感兴趣的:(JDBC)