數據庫開發三:JDBC數據庫開發入門三(PrepareStatement的使用及預處理原理)

目錄

 

一PrepareStatement使用

二預處理原理


文章相關視頻出處:https://developer.aliyun.com/lesson_1694_13598?spm=5176.10731542.0.0.4a023fdbjxoV5w#_13598

一PrepareStatement使用

主要特點:防止sql注入、提升效率

當前數據庫:

代碼:

package jdbc;
import org.junit.Test;
import java.sql.*;
/**
 * Created by kevin on 2020/3/23.
 */
public class Demo3 {
    public boolean login(String name,String password){
        /**
         * 一、Connection
         * 二、Statement
         * 三、ResultSet
         */
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            String driverClassName = "com.mysql.cj.jdbc.Driver";
            String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";
            String mysqlUserName="root";
            String mysqlPassword="mysql";
            Class.forName(driverClassName);
            connection = DriverManager.getConnection(url,mysqlUserName,mysqlPassword);
            statement = connection.createStatement();
            String sql = "select * from stu WHERE name = '"+name+"'and password = '"+password+"'";
            resultSet = statement.executeQuery(sql);
            return resultSet.next();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(resultSet!=null){
                    resultSet.close();
                }
                if(statement!=null){
                    statement.close();
                }
                if(connection!=null){
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    @Test
    public void fun1(){
        String userName= "張三";
        String password="111111";
        String userName2= "錯名' or 'a'='a";
        String password2="錯密碼' or 'a'='a";
        //正常輸入
        System.out.println(login(userName,password));
        //sql注入越過正常邏輯判斷
        System.out.println(login(userName2,password2));
    }
}

輸出

通過PrepareStatement方式新建login2方法

  public boolean login2(String name,String password){
        /**
         * 一、Connection
         * 二、Statement
         * 三、ResultSet
         */
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            String driverClassName = "com.mysql.cj.jdbc.Driver";
            String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";
            String mysqlUserName="root";
            String mysqlPassword="mysql";
            Class.forName(driverClassName);
            connection = DriverManager.getConnection(url,mysqlUserName,mysqlPassword);
//            statement = connection.createStatement();
//            String sql = "select * from stu WHERE name = '"+name+"'and password = '"+password+"'";
//            resultSet = statement.executeQuery(sql);
            /**
             * PrepareStatement 方式
             * 1.給出sql模板:所有的參數使用?來替代
             * 2.調用Connection方法得到PrepareStatement
             */
            String sql = "select * from stu WHERE name = ? and password = ? ";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,name);
            preparedStatement.setString(2,password);
            resultSet = preparedStatement.executeQuery();
            return resultSet.next();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if(resultSet!=null){
                    resultSet.close();
                }
                if(preparedStatement!=null){
                    preparedStatement.close();
                }
                if(connection!=null){
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

 @Test
    public void fun1(){
        String userName= "張三";
        String password="111111";
        String userName2= "錯名' or 'a'='a";
        String password2="錯密碼' or 'a'='a";
        //正常輸入
        System.out.println(login2(userName,password));
        //sql注入越過正常邏輯判斷
        System.out.println(login2(userName2,password2));
    }

  fun1()方法login替換爲login2輸出結果:

 

二預處理原理

·前提:連接點數據庫必須支持預處理,基本數據庫都支持
·每個preparedStatement都與一個sql模板綁定在一起,先把sql模板給數據庫,數據庫先進行校驗,在進行編譯,執行時只是把參數傳遞過去
·若第二次執行,不需再次校驗語法,不用再次編譯,直接執行
mysql打開預編譯功能
useServerPrepStmts=true(是否使用預編譯)
cachePrepStmts=true(設置是否對預編譯使用local cache)
prepStmtCacheSize=256(指定了local cache的大小)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章