日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

更多內容,歡迎關注微信公眾號:全菜工程師小輝~

前幾天筆者發布了博客,手寫mybatis徹底搞懂框架原理。為了幫助初學者更好理解mybatis框架,這次講解一下JAVA的JDBC的運行過程。

JDBC的作用

JDBC的全稱是Java DataBase Connection,也就是Java數據庫連接,我們可以用它來操作關系型數據庫。JDBC接口及相關類在java.sql包和javax.sql包里。我們可以用它來連接數據庫,執行SQL查詢,存儲過程,并處理返回的結果。

JDBC接口讓Java程序和JDBC驅動實現了松耦合,使得切換不同的數據庫變得更加簡單。

 

徹底搞懂JDBC的運行過程

 

 

JDBC

JDBC的連接步驟

執行一次JDBC連接,分六個步驟進行:

1. 導入包

在程序中包含數據庫編程所需的JDBC類。大多數情況下,使用 import java.sql.* 就足夠了

2. 注冊JDBC驅動程序

需要初始化驅動程序,這樣就可以打開與數據庫的通信。

3. 打開一個連接

使用DriverManager.getConnection()方法來創建一個Connection對象,它代表一個數據庫的物理連接。

4. 執行一個查詢

需要使用一個類型為Statement或PreparedStatement的對象(兩者區別看后文),并提交一個SQL語句到數據庫執行查詢。

5. 從結果集中提取數據

這一步中演示如何從數據庫中獲取查詢結果的數據。使用ResultSet.getXXX()方法來檢索的數據結果

6. 清理環境資源

在使用JDBC與數據交互操作數據庫中的數據后,應該明確地關閉所有的數據庫資源以減少資源的浪費。本文使用了try with resources方式關閉資源,這是JDK7的語法糖,讀者可自行搜索。

完整代碼如下。

//STEP 1. 導入包
import java.sql.*;
class JDBCExample {
 // JDBC驅動包名和數據庫的URL
 static final String JDBC_DRIVER = "com.MySQL.jdbc.Driver";
 static final String DB_URL = "jdbc:mysql://localhost/test";
 // 數據庫名和密碼自己修改
 static final String USER = "username";
 static final String PASS = "password";
 public static void main(String[] args) {
 String sql = "SELECT id, first, last, age FROM Employees";
 //STEP 2: 注冊JDBC驅動程序
 try {
 Class.forName(JDBC_DRIVER);
 } catch (ClassNotFoundException e) {
 e.printStackTrace();
 }
 // try with resources方式關閉資源。
 //STEP 6: 清理環境資源
 try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
 Statement stmt = conn.createStatement();
 ResultSet rs = stmt.executeQuery(sql)) {
 //STEP 3: 打開一個連接
 System.out.println("Connecting to database...");
// Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
 //STEP 4: 執行一個查詢
 System.out.println("Creating statement...");
// Statement stmt = conn.createStatement();
// ResultSet rs = stmt.executeQuery(sql);
 //STEP 5: 從結果集中提取數據
 while (rs.next()) {
 // 根據列名獲取數據
 int id = rs.getInt("id");
 int age = rs.getInt("age");
 String first = rs.getString("first");
 String last = rs.getString("last");
 // 顯示結果
 System.out.print("ID: " + id);
 System.out.print(", Age: " + age);
 System.out.print(", First: " + first);
 System.out.println(", Last: " + last);
 }
 } catch (SQLException se) {
 // 處理可能出現的錯誤
 se.printStackTrace();
 }
 System.out.println("Goodbye!");
 }
}

JDBC的最佳實踐

  • 數據庫資源是非常昂貴的,用完了應該盡快關閉它。Connection, Statement, ResultSet等JDBC對象都有close方法,調用它就好了。
  • 在代碼中必須顯式關閉掉ResultSet,Statement,Connection,如果你用的是連接池的話,連接用完后會放回池里,但是沒有關閉的ResultSet和Statement就會造成資源泄漏了。
  • 在finally塊中關閉資源,保證即便出了異常也能正常關閉。
  • 大量相似的查詢應當使用批處理完成。
  • 盡量使用PreparedStatement而不是Statement,以避免SQL注入,同時還能通過預編譯和緩存機制提升執行的效率。
  • 如果你要將大量數據讀入到ResultSet中,應該合理的設置fetchSize以便提升性能。
  • 你用的數據庫可能沒有支持所有的隔離級別,用之前先仔細確認下。
  • 數據庫隔離級別越高性能越差,確保你的數據庫連接設置的隔離級別是最優的。
  • 如果你需要長時間對ResultSet進行操作的話,盡量使用離線的RowSet。

FAQ

JDBC是如何實現Java程序和JDBC驅動的松耦合?

JDBC API使用Java的反射機制來實現Java程序和JDBC驅動的松耦合。看一下上文的JDBC示例,你會發現所有操作都是通過JDBC接口完成的,而驅動只有在通過Class.forName反射機制來加載的時候才會出現。

這是Java核心庫里反射機制的最佳實踐之一,它使得應用程序和驅動程序之間進行了隔離,讓遷移數據庫的工作變得更簡單。

Statement和PreparedStatement區別

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

預編譯

創建時的區別:

Statement statement = conn.createStatement();
PreparedStatement preStatement = conn.prepareStatement(sql);

執行時的區別:

ResultSet rSet = statement.executeQuery(sql);
ResultSet pSet = preStatement.executeQuery();

由上可以看出,PreparedStatement有預編譯的過程,已經綁定sql,之后無論執行多少次,都不會再去進行編譯,而Statement 不同,如果執行多次,則相應的就要編譯多少次sql,所以從這點看,PreparedStatement的效率會比Statement要高一些。PreparedStatement是預編譯的,所以可以有效的防止SQL注入等問題

占位符

PrepareStatement可以替換變量在SQL語句中可以包含?,可以用?替換成變量。

ps = conn.prepareStatement("select * from Employees where id=?");
int sid = 1001;
ps.setInt(1, sid);
rs = ps.executeQuery();

而Statement只能用字符串拼接。

int sid = 1001;
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from Employees where id=" + sid);

JDBC的ResultSet

在查詢數據庫后會返回一個ResultSet,它就像是查詢結果集的一張數據表。

ResultSet對象維護了一個游標,指向當前的數據行。開始的時候這個游標指向的是第一行。如果調用了ResultSet的next()方法游標會下移一行,如果沒有更多的數據了,next()方法會返回false。可以在for循環中用它來遍歷數據集。

默認的ResultSet是不能更新的,游標也只能往下移。也就是說你只能從第一行到最后一行遍歷一遍。不過也可以創建可以回滾或者可更新的ResultSet,像下面這樣。

Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);

當生成ResultSet的Statement對象要關閉或者重新執行或是獲取下一個ResultSet的時候,ResultSet對象也會自動關閉。

可以通過ResultSet的getter方法,傳入列名或者從1開始的序號來獲取列數據。

ResultSet的不同類型

根據創建Statement時輸入參數的不同,會對應不同類型的ResultSet。如果你看下Connection的方法,你會發現createStatement和prepareStatement方法重載了,以支持不同的ResultSet和并發類型。

ResultSet對象有三種類型。

  1. ResultSet.TYPE_FORWARD_ONLY:這是默認的類型,它的游標只能往下移。
  2. ResultSet.TYPE_SCROLL_INSENSITIVE:游標可以上下移動,一旦它創建后,數據庫里的數據再發生修改,對它來說是透明的。
  3. ResultSet.TYPE_SCROLL_SENSITIVE:游標可以上下移動,如果生成后數據庫還發生了修改操作,它是能夠感知到的。

ResultSet有兩種并發類型。

  1. ResultSet.CONCUR_READ_ONLY:ResultSet是只讀的,這是默認類型。
  2. ResultSet.CONCUR_UPDATABLE:我們可以使用ResultSet的更新方法來更新里面的數據。

更多內容,歡迎關注微信公眾號:全菜工程師小輝~

分享到:
標簽:JDBC
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定