亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Mybatis中ResultSetHandler的用法

發布時間:2021-06-28 17:41:22 來源:億速云 閱讀:204 作者:chen 欄目:大數據

本篇內容介紹了“Mybatis中ResultSetHandler的用法”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

    mybatis-3.4.6.release.

    ResultSetHandler是個接口,如List-1

    List-1

public interface ResultSetHandler {
  //將結果轉換為List
  <E> List<E> handleResultSets(Statement stmt) throws SQLException;
  //將結果轉換為游標Cursor
  <E> Cursor<E> handleCursorResultSets(Statement stmt) throws SQLException;

  void handleOutputParameters(CallableStatement cs) throws SQLException;
}

    實現類只有DefaultResultSetHandler,實現有點復雜,因為要考慮的情況很多。

    結果封裝原理

    List-2

<resultMap type="Person" id="resultPersonMap">
    <result property="id" column="id"/>
    <result property="username" column="username"/>
    <result property="password" column="password"/>
    <result property="fltNum" column="flt_num"/>
</resultMap>

    如List-2, 定義這樣一個ResultMap后,使用ObjectFactory創建一個Person對象,

person.setId(resultSet.getInt("id"))

person.setUsername(resultSet.getString("username"))

person.setPassword(resultSet.getString("password"))

person.setFltNum(resultSet.getString("flt_num"))

    不過這個轉換過程在實現上很復雜,其中就用到TypeHandler。

    開始之前,來看下ResultSetWrapper,如下List-3,通過ResultSet獲取ResultSetMetaData來獲取列的屬性,遍歷列,獲取列名稱、列類型、對應的JdbcType。

    List-3

public ResultSetWrapper(ResultSet rs, Configuration configuration) throws SQLException {
    super();
    this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
    this.resultSet = rs;
    final ResultSetMetaData metaData = rs.getMetaData();
    final int columnCount = metaData.getColumnCount();
    for (int i = 1; i <= columnCount; i++) {
        columnNames.add(configuration.isUseColumnLabel() ? metaData.getColumnLabel(i) : metaData.getColumnName(i));
        jdbcTypes.add(JdbcType.forCode(metaData.getColumnType(i)));
        classNames.add(metaData.getColumnClassName(i));
    }
}

    來看DefaultResultSetHandler的handleResultSets方法,

    List-4

public List<Object> handleResultSets(Statement stmt) throws SQLException {
    ErrorContext.instance().activity("handling results").object(mappedStatement.getId());
    final List<Object> multipleResults = new ArrayList<Object>();
    int resultSetCount = 0;
    ResultSetWrapper rsw = getFirstResultSet(stmt);//1

    List<ResultMap> resultMaps = mappedStatement.getResultMaps();//2
    int resultMapCount = resultMaps.size();
    validateResultMapsCount(rsw, resultMapCount);//3
    while (rsw != null && resultMapCount > resultSetCount) {
        ResultMap resultMap = resultMaps.get(resultSetCount);//4
        handleResultSet(rsw, resultMap, multipleResults, null);//5
        rsw = getNextResultSet(stmt);
        cleanUpAfterHandlingResultSet();
        resultSetCount++;
    }

    String[] resultSets = mappedStatement.getResultSets();
    if (resultSets != null) {
        while (rsw != null && resultSetCount < resultSets.length) {
        ResultMapping parentMapping = nextResultMaps.get(resultSets[resultSetCount]);
        if (parentMapping != null) {
            String nestedResultMapId = parentMapping.getNestedResultMapId();
            ResultMap resultMap = configuration.getResultMap(nestedResultMapId);
            handleResultSet(rsw, resultMap, null, parentMapping);
        }
        rsw = getNextResultSet(stmt);
        cleanUpAfterHandlingResultSet();
        resultSetCount++;
        }
    }
    return collapseSingleResultList(multipleResults);
}

1處通過ResultSetMetadata獲取列的屬性

2處獲取我們定義的resultMap,如List-2

3處驗證resultMap個數,如果小于1則會報錯

4處獲取resultMap,從List中

5處是核心,調用handleResultSet->handleRowValues->handleRowValuesForSimpleResultMap

    List-5

private void handleRowValuesForSimpleResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping)
    throws SQLException {
    DefaultResultContext<Object> resultContext = new DefaultResultContext<Object>();
    skipRows(rsw.getResultSet(), rowBounds);
    while (shouldProcessMoreRows(resultContext, rowBounds) && rsw.getResultSet().next()) {
        ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(rsw.getResultSet(), resultMap, null);
        Object rowValue = getRowValue(rsw, discriminatedResultMap);//1
        storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());
    }
}

    handleRowValuesForSimpleResultMap方法中,不斷調用resultSet.next()方法,會獲取resultSet中的所有數據。

    List-5的1處,調用getRowValue方法,該方法獲取resultSet中的一行數據,并將數據封裝位對象

    List-6

private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap) throws SQLException {
    final ResultLoaderMap lazyLoader = new ResultLoaderMap();
    Object rowValue = createResultObject(rsw, resultMap, lazyLoader, null);//1
    if (rowValue != null && !hasTypeHandlerForResultObject(rsw, resultMap.getType())) {
        final MetaObject metaObject = configuration.newMetaObject(rowValue);
        boolean foundValues = this.useConstructorMappings;
        if (shouldApplyAutomaticMappings(resultMap, false)) {
        foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, null) || foundValues;//2
        }
        foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, null) || foundValues;
        foundValues = lazyLoader.size() > 0 || foundValues;
        rowValue = foundValues || configuration.isReturnInstanceForEmptyRow() ? rowValue : null;
    }
    return rowValue;
}

    List-6中1處,通過反射,創建Person對象(如List-7),之后在List-6的2處

    List-7

<select id="findByUsername" resultType="Person" parameterType="Person">
    select * from person where username=#{username};
</select>

    List-8

private boolean applyAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
    List<UnMappedColumnAutoMapping> autoMapping = createAutomaticMappings(rsw, resultMap, metaObject, columnPrefix);
    boolean foundValues = false;
    if (!autoMapping.isEmpty()) {
        for (UnMappedColumnAutoMapping mapping : autoMapping) {
        final Object value = mapping.typeHandler.getResult(rsw.getResultSet(), mapping.column);
        if (value != null) {
            foundValues = true;
        }
        if (value != null || (configuration.isCallSettersOnNulls() && !mapping.primitive)) {
            // gcode issue #377, call setter on nulls (value is not 'found')
            metaObject.setValue(mapping.property, value);
        }
        }
    }
    return foundValues;
}

    List-8中,createAutomaticMappings方法返還sql查詢的列屬性——從ResultSetWrapper中獲取的,之后遍歷這些列,對每一列,都調用typeHandler.getResult方法獲取值,之后用metaObject.setValue,內部通過反射的方式設置值。這樣createAutomaticMappings方法執行完成后,就獲取了resultSet中的一行數據,且封裝到對象中了。

    回到List-5中,getRowValue方法返回值,storeObject方法中將值放入到List中。

    描述較為泛華,建議個人閱讀源碼。此外,比如懶加載在ResultSetHandler中實現。

Reference

  1. https://github.com/mybatis/mybatis-3/tree/3.4.x

“Mybatis中ResultSetHandler的用法”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

漳州市| 始兴县| 盱眙县| 三江| 乳源| 兴文县| 吉安县| 北辰区| 临夏市| 上虞市| 瑞丽市| 宜黄县| 迭部县| 嘉兴市| 渝北区| 道真| 象山县| 黎川县| 颍上县| 麻江县| 温泉县| 伊通| 玉屏| 股票| 贺兰县| 台江县| 云龙县| 衡南县| 铅山县| 凤山市| 南川市| 苍山县| 肃北| 吉林省| 印江| 郧西县| 武川县| 安康市| 宁波市| 那曲县| 同仁县|