🚀 作者主頁: 有來技術
🔥 開源項目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot
🌺 倉庫主頁: Gitee 💫 Github 💫 GitCode
💖 歡迎點贊 👍 收藏 ?留言 📝 如有錯誤敬請糾正!
目錄
- 前言
- ResultSetHandler 簡介與作用
- ResultSetHandler 接口
- DefaultResultSetHandler 類
- handleResultSets
- handleResultSet
- handleRowValues
- 結語
- 開源項目
前言
MyBatis 是一款廣受歡迎的 Java 持久層框架,其中的四大核心組件之一是 ResultSetHandler。ResultSetHandler 負責處理 JDBC 查詢返回的 ResultSet,并將結果映射成 Java 對象。本文將深入解析 ResultSetHandler 的源碼,探討其實現原理、核心方法,以及在 MyBatis 中的作用。
ResultSetHandler 簡介與作用
在 MyBatis 中,ResultSetHandler 起到了重要的橋梁作用。當我們執行查詢操作時,JDBC 會返回一個 ResultSet 對象,而 ResultSetHandler 就負責將這個 ResultSet 轉化為 Java 對象。具體而言,ResultSetHandler 的作用包括:
- 結果集映射: 將 ResultSet 中的數據映射到 Java 對象上,形成查詢結果。
- 多結果集處理: 處理存儲過程等情況下的多結果集返回。
- 懶加載處理: 處理延遲加載,將查詢結果中的延遲加載的部分進行懶加載。
ResultSetHandler 接口
ResultSetHandler 是 MyBatis 中的一個接口,定義了處理結果集的方法。核心方法包括:
handleResultSets(Statement stmt)
: 處理包含多個 ResultSet 的情況,返回一個包含映射結果的 List。handleOutputParameters(CallableStatement cs)
: 處理存儲過程等情況下的輸出參數。handleResultSets(Statement stmt, int resultSetType)
: 處理指定 ResultSet 類型的情況。handleCursorResultSets(Statement stmt)
: 處理存儲過程等情況下的游標結果集。
DefaultResultSetHandler 類
DefaultResultSetHandler 是 ResultSetHandler 接口的默認實現類,負責處理結果集映射的具體邏輯。以下是 DefaultResultSetHandler 中的核心方法:
handleResultSets
該方法負責處理多個 ResultSet 的情況,將每個 ResultSet 映射成 Java 對象,并最終返回映射結果的列表。
@Override
public List<Object> handleResultSets(Statement stmt) throws SQLException {ErrorContext.instance().activity("handling results").object(mappedStatement.getId());// 處理多個 ResultSet 的情況List<Object> multipleResults = new ArrayList<>();int resultSetCount = 0;ResultSetWrapper rsw = getFirstResultSet(stmt);// 遍歷結果集while (rsw != null && !rsw.isClosed() && rsw.getResultSet().getStatement().getMoreResults()) {handleResultSet(rsw, multipleResults, resultSetCount);rsw = getNextResultSet(stmt);cleanUpAfterHandlingResultSet();resultSetCount++;}// 處理多結果集時的映射邏輯return collapseSingleResultList(multipleResults);
}
handleResultSet
該方法用于處理單個 ResultSet 的映射邏輯,包括處理簡單的映射關系和嵌套結果集。在處理單個 ResultSet 時,調用 handleRowValues 方法進行映射。
private void handleResultSet(ResultSetWrapper rsw, List<Object> multipleResults, int resultSetCount) throws SQLException {List<ResultMap> resultMaps = mappedStatement.getResultMaps();ResultMap resultMap = resultMaps.get(resultSetCount);// 處理單個 ResultSet 的映射邏輯handleRowValues(rsw, resultMap, multipleResults, null);// 處理嵌套結果集if (resultMap.hasNestedResultMaps()) {handleRowValuesForNestedResultMap(rsw, resultMap, multipleResults, null);}
}
handleRowValues
該方法用于處理單行記錄的映射關系,根據是否存在嵌套結果集分別調用 handleRowValuesForSimpleResultMap 或 handleRowValuesForNestedResultMap 方法。
private void handleRowValues(ResultSetWrapper rsw, ResultMap resultMap, List<Object> multipleResults, ResultMapping parentMapping) throws SQLException {if (resultMap.hasNestedResultMaps()) {ensureNoRowWithNestedResultMap(rsw, resultMap);} else {// 處理簡單的映射關系handleRowValuesForSimpleResultMap(rsw, resultMap, multipleResults, parentMapping);}
}
結語
通過深度解析 ResultSetHandler 的源碼,我們更清晰地了解了其在 MyBatis 中的核心作用。ResultSetHandler 不僅完成了結果集到 Java 對象的映射,還處理了多結果集、嵌套結果集等復雜場景。熟悉 ResultSetHandler 的源碼實現,有助于我們更好地理解 MyBatis 的內部機制,提高對查詢操作的靈活應用。
開源項目
- SpringCloud + Vue3 微服務商城
Github | Gitee | |
---|---|---|
后端 | youlai-mall 🍃 | youlai-mall 🍃 |
前端 | mall-admin🌺 | mall-admin 🌺 |
移動端 | mall-app 🍌 | mall-app 🍌 |
- SpringBoot 3+ Vue3 單體權限管理系統
Github | Gitee | |
---|---|---|
后端 | youlai-boot 🍃 | youlai-boot 🍃 |
前端 | vue3-element-admin 🌺 | vue3-element-admin 🌺 |