• 从源码角度分析Mybatis级联映射的实现原理


    Mybatis是一个半自动化ORM框架,可以将数据库中的记录转换为java实体对象,但是java实体属性通常采用驼峰命名法,而数据库字段习惯采用下划线分隔命名法,因此需要用户指定java实体属性与数据库表字段之间的映射关系。 mybatis的Mapper 配置中提供了resultMap 标签,用于建立数据库字段与java实体属性之间的映射关系。例如:

     
        
        
        
        
        
          
          
          
        
      
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Mybatis 在启动时,所有配置信息都会被转换为java对象,Mybatis 通过ResultMap类描述resultMap标签的配置信息;在XMLMapperBuilder类的configurationElement()方法中,调用resultMapElements()方法对所有resultMap标签进行解析。resultMapElements()方法最终会调用重载的resultMapElement()方法对每个resultMap标签进行解析。代码如下:
    在这里插入图片描述

    对resultMap标签解析完成后,在StatementHandler组件与数据库完成交互后,需要根据resultMap标签的配置把结果转换为Resultmap对象,就会使用ResultSetHandler组件对结果集进行处理。

    在PreparedStatementHandler.query方法中,调用PreparedStatement.execute() 方法完成与数据库交互之后,会调用resultSetHandler.handleResultSets()方法对结果集进行处理。代码如下:
    在这里插入图片描述
    DefaultResultSetHandler类是ResultSetHandler接口的唯一默认实现,DefaultResultSetHandler.handleResultSets()方法中,简化了对JDBC中ResultSet对象的操作,将ResultSet对象包装成ResultSetWrapper对象,然后获取MappedStatement对象对应的ResultMap对象,然后再调用重载的HandleResultSet()方法进行处理,代码如下:
    在这里插入图片描述

    在重载的handleResultSet()方法中做了些逻辑判断,最终都会调用handleRowValues()方法进行处理,代码如下:
    在这里插入图片描述
    handleRowValues()方法中判断ResultMap中是否有嵌套的ResultMap,当使用association或collection标签通过JOIN查询方式进行级联映射时 ,HasNestedResultMaps()方法返回true;如果有嵌套的RresultMap,则调用handleRowValuesForNestedResultMap()方法进行处理,否则调用handleRowValuesForSimpleResultMap()方法,代码如下:
    在这里插入图片描述

    简单映射结果处理

    handleRowValuesForSimpleResultMap()方法不含嵌套映射的简单映射的处理。
    在这里插入图片描述

    嵌套映射结果处理

    handleRowValuesForNestedResultMap ()方法是对嵌套映射结果进行处理,在处理过程中,对结果集对象进行遍历,处理每一行数据,首先调用resolveDiscriminatedResultMap()方法处理resultmap标签中通过discriminator标签配置的鉴别器信息,根据字段值获取对应的ResultMap对象,然后调用getRowValue() 方法将结果集中的一行数据转换为java实体对象。
    在这里插入图片描述
    简单映射结果和嵌套映射结果调用了getRowValue() 方法将结果集中的一行数据转换为java实体对象。代码如下:
    在这里插入图片描述

    多结果集处理

    针对多结果集处理,在getRowValue()方法中调用 applyPropertyMappings()方法映射ResultMap中明确指定的字段。代码如下:
    在这里插入图片描述
    applyPropertyMappings()会调用getPropertyMappingValue()方法完成映射操作,代码如下:
    在这里插入图片描述

    getPropertyMappingValue()会调用addPendingChildRelation()对多结果集的情况进行处理,处理代码如下:

    在这里插入图片描述

  • 相关阅读:
    @Builder使用遇到的坑
    QMudiaPlayer(状态)
    【数据结构基础_图】Leetcode 997.找到小镇的法官
    代理IP和Socks5代理在游戏领域的重要应用
    Doris:使用表函数explode实现array字段列转行
    表单制作软件有哪些?最火的8款表格制作软件?
    MySQL-3-多表查询和事务(结合案例学习)
    Oracle常用函数大全
    python讲解(2)
    工具、技巧【个人专用】如何在CSND编辑器内输出带颜色的字体?Markdown编辑器——字体、字号、颜色使用全解
  • 原文地址:https://blog.csdn.net/tang_huan_11/article/details/125482288