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

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和Nested Results,先看下select:

    <resultMap id="citySelectCountryResultMap" type="CityCountry">
        <id property="id" column="ID" javaType="long" jdbcType="INTEGER" />
        <result property="name" column="Name"/>
        <result property="district" column="district"/>
        <result property="population" column="population"/>
        <association property="country" column="CountryCode" javaType="Country" select="getCountryByCode"/>
    </resultMap>

CityCountry类中加了一个Country属性,Country类对应country表,选择几个字段,不用全部一一对应:

猜你喜欢

转载自blog.csdn.net/lnlllnn/article/details/81157122