​mybatis collection解析以及和association的区别

   说到mybatis的collection标签,我们肯定不陌生,可以通过它解决一对多的映射问题,举个例子一个用户对应多个系统权限,通过对用户表和权限表的关联查询我们可以得到好多条记录,但是用户信息这部分在多条记录中是重复的,只有权限不同,我们需要把这多条权限记录映射到这个用户之中,这个时候可以通过collection标签/association标签来解决(虽然assocation标签一般是解决一对一问题的,但它实际上也能实现我们的需求,可以通过后面的源码看出来)

1.1 相关代码和运行结果

实体类和mapper代码

public class Test {

  public static void main(String[] args) throws IOException {

    try (InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml")) {
      // 构建session工厂 DefaultSqlSessionFactory
      SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
      SqlSession sqlSession = sqlSessionFactory.openSession();
      UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
      UserDO userDO = userMapper.getByUserId(1);
      System.out.println(userDO);
    }
  }

}

运行结果如下,可以看到权限记录映射到属性permitDOList 的list列表了

1.2 collection部分源码解析

通过PreparedStatement查询完之后得到ResultSet结果集,之后需要将结果集解析为java的pojo类中,下面通过源码简单讲下是如何解析的

  public void handleRowValues(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
    // 是否有嵌套的resultMaps
    if (resultMap.hasNestedResultMaps()) {
      ensureNoRowBounds();
      checkResultHandler();
      handleRowValuesForNestedResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
    } else {
      // 无嵌套
      handleRowValuesForSimpleResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
    }
  }

根据有无嵌套分成两层逻辑,有嵌套resultMaps就是指<resultMap>标签下有子标签<collection>或<association>,分析下第一层

  private void handleRowValuesForNestedResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
    final DefaultResultContext<Object> resultContext = new DefaultResultContext<>();
    ResultSet resultSet = rsw.getResultSet();
    // 跳过offset行
    skipRows(resultSet, rowBounds);
    // 上一次获取的数据
    Object rowValue = previousRowValue;
    // 已获取记录数量小于limit
    while (shouldProcessMoreRows(resultContext, rowBounds) && !resultSet.isClosed() && resultSet.next()) {
      // 鉴别器解析
      final ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(resultSet, resultMap, null);
      // 创建缓存key resultMapId + (columnName + columnValue)....
      final CacheKey rowKey = createRowKey(discriminatedResultMap, rsw, null);
      // 部分对象(可能存在对象内容缺失未完全合并)
      Object partialObject = nestedResultObjects.get(rowKey);
      // issue #577 && #542
      // 关于resultOrdered的理解,举例若查询得到四条记录a,a,b,a , 相同可以合并。
      // 那么当resultOrdered=true时,最后可以得到三条记录,第一条和第二条合并成一条、第三条单独一条、第四条也是单独一条记录
      // resultOrdered=false时,最后可以得到两条记录,第一条、第二条和第四条会合并成一条,第三条单独一条记录
      // 另外存储到resultHandler的时机也不一样,resultOrdered=true是等遇到不可合并的记录的时候才把之前已经合并的记录存储,
      // 而resultOrdered=false是直接存储的后续有合并的记录再处理添加到集合属性中
      if (mappedStatement.isResultOrdered()) {
        // partialObject为null,说明这一条记录不可与上一条记录进行合并了,那么清空nestedResultObjects防止之后出现有可合并的记录的时候继续合并
        // 然后将记录存储到resultHandler里面
        if (partialObject == null && rowValue != null) {
          nestedResultObjects.clear();
          storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
        }
        rowValue = getRowValue(rsw, discriminatedResultMap, rowKey, null, partialObject);
      } else {
        // 处理resultSet的当前这一条记录
        rowValue = getRowValue(rsw, discriminatedResultMap, rowKey, null, partialObject);
        if (partialObject == null) {
          // 将记录存储到resultHandler里面
          storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
        }
      }
    }

这段代码主要是创建了一个缓存key,主要是根据resultMapId和<id>标签的column和对应的columvalue来创建的(若没有<id>标签,则会使用所有的<result>标签的column和columnValue来创建),以此缓存键来区分记录是否可合并。nestedResultObjects是一个储存结果的map,以缓存键为key,实体类(本例中为UserDO)为value,若能以cacheKey取到值,则说明本条记录可合并。http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%AE%A2%E6%9C%8D13O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%AE%A2%E6%9C%8D%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%AE%A2%E6%9C%8D%E7%99%BB%E5%BD%9513O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%AE%A2%E6%9C%8D%E7%99%BB%E5%BD%95%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%AE%A2%E6%9C%8D%E7%94%B5%E8%AF%9D13O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%AE%A2%E6%9C%8D%E7%94%B5%E8%AF%9D%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%AE%A2%E6%9C%8D%E9%83%A813O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%AE%A2%E6%9C%8D%E9%83%A8%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%A4%96%E8%81%94%E9%83%A813O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%A4%96%E8%81%94%E9%83%A8%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%85%AC%E5%8F%B8%E6%8E%A5%E9%80%8113O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%85%AC%E5%8F%B8%E6%8E%A5%E9%80%81%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E7%94%B5%E8%AF%9D%E6%8A%95%E6%B3%A813O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E7%94%B5%E8%AF%9D%E6%8A%95%E6%B3%A8%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E6%89%8B%E6%9C%BA%E4%B8%8B%E8%BD%BD13O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E6%89%8B%E6%9C%BA%E4%B8%8B%E8%BD%BD%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E4%B8%8B%E8%BD%BD%E7%BD%91%E7%AB%9913O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E4%B8%8B%E8%BD%BD%E7%BD%91%E7%AB%99%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E6%B3%A8%E5%86%8C%E7%BD%91%E7%AB%9913O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E6%B3%A8%E5%86%8C%E7%BD%91%E7%AB%99%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E7%BD%91%E7%AB%99%E6%B3%A8%E5%86%8C13O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E7%BD%91%E7%AB%99%E6%B3%A8%E5%86%8C%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%AE%98%E7%BD%9113O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%AE%98%E7%BD%91%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E7%99%BB%E9%99%86%E7%BD%91%E5%9D%8013O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E7%99%BB%E9%99%86%E7%BD%91%E5%9D%80%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E6%80%8E%E4%B9%88%E6%B3%A8%E5%86%8C13O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E6%80%8E%E4%B9%88%E6%B3%A8%E5%86%8C%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E6%80%8E%E4%B9%88%E5%85%85%E5%80%BC13O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E6%80%8E%E4%B9%88%E5%85%85%E5%80%BC%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%BC%80%E6%88%B7%E7%94%B5%E8%AF%9D13O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%BC%80%E6%88%B7%E7%94%B5%E8%AF%9D%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E8%81%94%E7%B3%BB13O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E8%81%94%E7%B3%BB%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E6%80%8E%E4%B9%88%E8%81%94%E7%B3%BB13O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E6%80%8E%E4%B9%88%E8%81%94%E7%B3%BB%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%B9%B3%E5%8F%B013O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E5%B9%B3%E5%8F%B0%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E7%BC%85%E7%94%B8%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B913O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E7%BC%85%E7%94%B8%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E9%9B%86%E5%9B%A213O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E9%9B%86%E5%9B%A2%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E4%BB%A3%E7%90%86%E7%99%BB%E9%99%8613O952222I5_1s.htm
http://house.china.com.cn/sousuo/%E6%9E%9C%E5%8D%9A%E4%B8%9C%E6%96%B9%E4%BB%A3%E7%90%86%E7%99%BB%E9%99%86%E3%80%90%E7%BD%91%E5%9D%80Ny68%C2%B7CC%E3%80%91_1s.htm
http://house.china.com.cn/sousuo/%E6%9

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值