本期目標
追蹤
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方法的執行流程實際上應該是有一定標準的,而逐級呼叫的過程,實際上就是在給其增加預設配置,使其能按標準執行的過程。