PGjdbc原始碼試讀(二)

li-羡鱼發表於2024-08-02

本期目標

追蹤

Connection.createStatement()
Statement.executeUpdate(String sql)

追蹤

Connection.createStatement()

在PgConnection中找到createStatement()方法:

該方法呼叫了同名方法,並傳遞了兩個引數,查詢兩個常量的註釋:


TYPE_FORWARD_ONLY 表示返回的集合ResultSet只能順序正向遍歷。
CONCUR_READ_ONLY 表示返回的集合ResultSet只可以讀取其中的資料,不允許修改集合中的資料。

繼續追蹤到:

該方法首先呼叫isClosed()方法檢查連線是否被close,在連線正常情況下才會繼續執行,否則會throw exception。
繼而再次呼叫新的同名方法,傳遞了三個引數,增加的引數透過getHoldability()方法獲得,該方法如下:

我們發現該方法實際上返回了PgConnection的一個屬性,該屬性:

即傳遞的第三個引數實際上等價於:ResultSet.CLOSE_CURSORS_AT_COMMIT,參考註釋如下:

因而三個引數實際上為:

TYPE_FORWARD_ONLY 表示返回的集合ResultSet只能順序正向遍歷。
CONCUR_READ_ONLY 表示返回的集合ResultSet只可以讀取其中的資料,不允許修改集合中的資料。
CLOSE_CURSORS_AT_COMMIT 表示表示修改提交時當前ResultSet結果集關閉

繼續追蹤至:

我們發現其呼叫了PgStatement的建構函式,傳遞了之前三個引數,並將當前連線作為一個新的引數傳遞。
追蹤該建構函式:

Statement.executeUpdate(String sql)

在PGStatement中找到該方法:

該方法核心部分呼叫了三個方法,對其依次進行追蹤:

executeWithFlags(sql, QueryExecutor.QUERY_NO_RESULTS)

QUERY_NO_RESULTS:這個常量用於標記查詢執行時的一個特定標誌,表明執行該查詢時並不期望返回結果集。
結構如下:

其呼叫了executeCachedSql方法,並傳遞了三個引數,新增的引數為:

推測該引數應該用於標識無返回列的情況。

繼續向下追蹤:

preferQueryMode(String) 預設值:extended 意義:指定使用哪種模式對資料庫執行查詢:

simple 表示(‘Q’ execute,無解析,無繫結,僅文字模式),
extended 表示始終使用繫結/執行訊息,
extendedForPrepared 表示僅針對準備好的語句進行擴充套件,
extendedCacheEverything 表示使用extended協議並嘗試將每個語句(包括Statement.execute(String sql))快取在查詢快取中。

查詢鍵的主要作用是為特定的SQL查詢或命令生成一個唯一的識別符號,這個識別符號用於在快取中查詢、儲存或驗證查詢的結果。當應用程式執行一個查詢時,查詢快取機制(如果啟用了的話)會首先檢查是否已經為相同的查詢(即具有相同查詢鍵的查詢)快取了結果。如果是,就可以直接返回快取中的結果,而無需再次執行實際的資料庫查詢,從而節省時間和資源。

最後的查詢過程在

  res = executeWithFlags(cachedQuery, flags)

處實現,未詳述。
executeCachedSql(String sql, int flags,String @Nullable [] columnNames) 方法關聯要素較多,除少數註釋外,將單獨記錄,此處不再詳述。

checkNoResultUpdate()

該方法檢查上一步呼叫的executeWithFlags方法是否正常執行,按照邏輯,其不會產生查詢結果,若其產生了,則throw Exception,指示有異常產生。
需要注意的是,PgStatement類中查詢方法的查詢結果是儲存在result屬性中的,不會在直接查詢的方法直接return,故該檢查即為檢查result是否為空。

getUpdateCount()

返回最近一次執行executeUpdate方法時影響的行數,未細究

debug

在之前追蹤到的幾個關鍵函式部分打上斷點,除錯執行。

如上圖所示,傳遞空陣列,其起到標識作用


preferQueryMode實際就是這個queryExecutor物件的preferQueryMode屬性

總結

  • Connection.createStatement(),無傳遞引數,其將以一系列事先約定好的預設值取作為PgStatement的構造方法引數,以此構造出一個PgStatement物件。用到的預設值如下:

TYPE_FORWARD_ONLY 表示返回的集合ResultSet只能順序正向遍歷。
CONCUR_READ_ONLY 表示返回的集合ResultSet只可以讀取其中的資料,不允許修改集合中的資料。
CLOSE_CURSORS_AT_COMMIT 表示表示修改提交時當前ResultSet結果集關閉

  • Statement.executeUpdate(String sql),該方法調的最底層execute方法的執行流程實際上應該是有一定標準的,而逐級呼叫的過程,實際上就是在給其增加預設配置,使其能按標準執行的過程。

相關文章