Mybatis源码阅读9 --- ResultMap-处理返回值

本文深入探讨了Mybatis中的ResultMap如何处理返回结果,包括id、result、association、collection和discriminator等元素。ResultMap主要用于处理复杂的查询结果,例如1对1、1对多的关系映射。association用于处理1对1关系,可通过nested select或nested results避免N+1问题。collection则解决1对多问题,提供nested select和nested results选项。同时,discriminator根据特定字段值返回不同类型的对象,增加了灵活性。
摘要由CSDN通过智能技术生成

sql语句无非增删改查,对于返回结果,增删改只需知道成功与否,查询就稍稍复杂,我们来看下mybatis如何处理的。在sql的select必须要定义返回resultType或者resultMap,resultType就是一个class对象(HashMap,自定义Java类如City),若返回类型稍稍复杂些就需要ResultMap了,ResultMap的元素:constructor、id、result、association、collection、discriminator。最基本的是id和result:

    <resultMap id="cityResultMap" type="City">
        <id property="id" column="ID" javaType="long" jdbcType="INTEGER" />
        <result property="name" column="Name"/>
        <result property="countryCode" column="CountryCode"/>
        <result property="district" column="district"/>
        <result property="population" column="population"/>
    </resultMap>

id和result就是select出的column映射到java对象属性的过程,除了property和column,还有另外三个属性:javaType、jdbcType、typeHandler,javaType和jdbcType一般不需指定(我还不清楚需要指定的情况),先瞧一眼构建出来的ResultMap:

没啥特殊的,构建完直接塞到configuration中去,构建select的MappedStatement时再从configuration取出来,最后在处理ResultSet时再使用(这里能看见一个MappedStatement可对应多个resultMap,暂时没有想到这种使用场景):

先从简单的(只定义id和property的resultMap:cityResultMap,方法->cityDao.getById)开始,继续debug(上图红框),发现会创建一个resultMap的type对象:

创建完对象就该给对象赋值了:

赋值前先check是否要自动mapping,AutoMappingBehavior有Null、Partial、None三个枚举值,默认为Partial,在cityDao.getById调用中,applyAutomaticMappings中并没有做什么,在applyPropertyMappings中,通过propertyMapping挨个通过metaObject给rowValue字段赋值并返回了rowValue,最终结果保存到这里了:

整个流程还是比较简单:拿到resultMap对象->创建返回对象->propertyMappings赋值->typeHandler取值->通过metaObject将返回值set到返回的对象->返回对象保存到DefaultResultHandler中并最终返回List对象。在看下带构造函数的resultMap:

    <resultMap id="cityConstructorResultMap" type="CityConstructor">
        <constructor>
            <idArg column="ID" name="id" javaType="java.lang.Long"/>
            <arg column="Name" name="name" javaType="java.lang.String"/>
            <arg column="CountryCode" name="countryCode" javaType="java.lang.String"/>
        </constructor>
        <result property="district" column="district"/>
        <result property="population" column="population"/>
    </resultMap>

何时回使用呢?当有些字段我并不想提供get方法时(听起来有道理,实际上还没碰见这种case),当resultMap有constructor元素时,创建的返回对象就是调用了带参数的构造函数:

继续看association,它的作用是处理1对1或者说拥有一个XXX,比如一个city,有一个country属性,association有两种方式:Nested Select

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值