JDBC之PreparedStatement 詳解


簡介

PreparedStatement 是一個特殊的Statement對象,如果我們只是來查詢或者更新數據的話,最好用PreparedStatement代替Statement,因為它有以下有點:

  1. 簡化Statement中的操作
  2. 提高執行語句的性能
  3. 可讀性和可維護性更好
  4. 安全性更好。
  5. 使用PreparedStatement能夠預防SQL注入攻擊,所謂SQL注入,指的是通過把SQL命令插入到Web表單提交或者輸入域名或者頁面請求的查詢字符串,最終達到欺騙服務器,達到執行惡意SQL命令的目的。注入只對SQL語句的編譯過程有破壞作用,而執行階段只是把輸入串作為數據處理,不再需要對SQL語句進行解析,因此也就避免了類似select * from user where name='aa' and password='bb' or 1=1的sql注入問題的發生。

Statement 和 PreparedStatement之間的關系和區別.

  • 關系:PreparedStatement繼承自Statement,都是接口
  • 區別:PreparedStatement可以使用占位符,是預編譯的,批處理比Statement效率高

入門使用

創建PreparedStatement

創建一個PreparedStatement PreparedStatement對象的創建也同樣離不開 DriverManger.getConnect()對象,因為它也是建立在連接到數據庫之上的操作。

      /** 1. init PreparedStatement*/
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/db_test?useSSL=false";
        String username = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, username, password);
        String sql = "update user set username=? where id = ?";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

設置入參

往PreparedStatement里寫入參數

看上面那個sql 字符串,中間有幾個?,它在這里有點占位符的意思,然后我們可以通過PreparedStatement的setString(),等方法來給占位符進行賦值,使得sql語句變得靈活。

        /** 2. prepare param*/
        preparedStatement.setString(1, "feifz");
        preparedStatement.setInt(2, 2);

參數中的第一個參數分別是1和2,它代表的是第幾個問號的位置。如果sql語句中只有一個問號,那就不用聲明這個參數。

執行更新

 /** 3. execute update*/
  int result = preparedStatement.executeUpdate();
  System.out.printf("更新記錄數:"+result+"\n");

結果:

更新記錄數:1

執行查詢

如果是執行查詢數據庫的話,也像Statement對象執行excuteQuery()一樣返回一個ResultSet結果集。

/** 4. execute select*/
String sql2 = "select * from user";
        ResultSet resultSet = preparedStatement.executeQuery(sql2);
        while (resultSet.next()) {
            int id = resultSet.getInt("id");
            String username = resultSet.getString("username");
            String dept = resultSet.getString("dept");
            System.out.println("id:"+id +"username->"+ username + ",dept-> " + dept );
        }

執行結果:

id:1username->Fant.J,dept-> 測試部
id:2username->feifz,dept-> 研發部
id:3username->xixi,dept-> 產品部
id:4username->hah,dept-> 集成部
id:5username->zeze,dept-> 研發部

完整代碼

package com.github.feifuzeng.middleware.mybatis.jdbc;

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

/**
 * @author feifz
 * @version 1.0.0
 * @Description PreparedStatement簡單demo
 * @createTime 2019年08月29日 20:21:00
 */
public class PrepareStatementSimpleDemo {

    public static void main(String[] args) throws Exception {

        /** 1. init PreparedStatement*/
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/db_test?useSSL=false";
        String user = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, user, password);
        String sql = "update user set username=? where id = ?";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        /** 2. prepare param*/
        preparedStatement.setString(1, "feifz");
        preparedStatement.setInt(2, 2);

        /** 3. execute update*/
        int result = preparedStatement.executeUpdate();
        System.out.printf("更新記錄數:"+result+"\n");

        /** 4. execute select*/

        String sql2 = "select * from user";
        ResultSet resultSet = preparedStatement.executeQuery(sql2);
        while (resultSet.next()) {
            int id = resultSet.getInt("id");
            String username = resultSet.getString("username");
            String dept = resultSet.getString("dept");
            System.out.println("id:"+id +"username->"+ username + ",dept-> " + dept );
        }


    }
}

參考

  1. https://juejin.im/post/5abb78c8f265da23994e9643

結語

歡迎關注微信公眾號『碼仔zonE』,專注於分享Java、雲計算相關內容,包括SpringBoot、SpringCloud、微服務、Docker、Kubernetes、Python等領域相關技術干貨,期待與您相遇!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM