JDBC之PreparedStatement 詳解
阿新 • • 發佈:2020-09-09
簡介
PreparedStatement 是一個特殊的Statement物件,如果我們只是來查詢或者更新資料的話,最好用PreparedStatement代替Statement,因為它有以下有點:
- 簡化Statement中的操作
- 提高執行語句的效能
- 可讀性和可維護性更好
- 安全性更好。
- 使用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 );
}
}
}
參考
結語
歡迎關注微信公眾號『碼仔zonE』,專注於分享Java、雲端計算相關內容,包括SpringBoot、SpringCloud、微服務、Docker、Kubernetes、Python等領域相關技術乾貨,期待與您相遇!