MyBatis源码分析——使用注解执行SQL

9 篇文章 0 订阅
6 篇文章 0 订阅

MyBatis源码分析

使用注解方式执行SQL

使用注解执行SQL只需在自定义Mapper接口上添加注解如@Select、@Insert、@Update、@Delete等,示例如下:

public interface UserMapper {
  @Select("select * from user where id = #{id}")
  User selectUser(@Param("id") Integer id);
}

那么便可使用getMapper获取代理对象后执行接口方法得到sql查询结果,不需再在Mapper.xml文件中写SQL。接下来从源码进行分析注解形式执行SQL的原理,相比于前面两种方式,注解的源码相对就比较简单。

MyBatis支持的注解都在包org.apache.ibatis.annotations中,而对于增删改查(@Insert、@Delete、@Update、@Select)注解的解析都在MapperAnnotationBuilder类中。
在这里插入图片描述
在MapperAnnotationBuilder类中有个parse()方法用于对使用注解的Mapper接口方法进行解析转换,parse()方法源码如下:
在这里插入图片描述
从源码中可以看到parse()方法中主要包含以下步骤:

  • 加载xml配置
  • 缓存初始化
  • 将使用注解的接口方法封装为MappedStatement对象

这里我们主要关注点在将使用注解的接口方法封装为MappedStatement对象上,也就是MapperAnnotationBuilder.parseStatement()方法。其源码如下(由于代码片段较长,这里只保留关键部分):

void parseStatement(Method method) {
    Class<?> parameterTypeClass = getParameterType(method);
    LanguageDriver languageDriver = getLanguageDriver(method);
    SqlSource sqlSource = getSqlSourceFromAnnotations(method, parameterTypeClass, languageDriver);
    if (sqlSource != null) {
        // ......省略
        assistant.addMappedStatement(
            mappedStatementId,
            sqlSource,
            statementType,
            sqlCommandType,
            fetchSize,
            timeout,
            // ParameterMapID
            null,
            parameterTypeClass,
            resultMapId,
            getReturnType(method),
            resultSetType,
            flushCache,
            useCache,
            // TODO gcode issue #577
            false,
            keyGenerator,
            keyProperty,
            keyColumn,
            // DatabaseID
            null,
            languageDriver,
            // ResultSets
            options != null ? nullOrEmpty(options.resultSets()) : null);
    }
  }

在parseStatement()方法中,利用反射获取了参数和注解中的SQL语句,然后将代码逻辑中构建好的各种对象(如sqlSource、statementType、sqlCommandType等)作为参数传给MapperBuilderAssistant.addMappedStatement()方法,来进行MappedStatement对象构建。在MapperBuilderAssistant.addMappedStatement()方法中,通过以下两句将构建好的MappedStatement传给Configuration对象

MappedStatement statement = statementBuilder.build();
configuration.addMappedStatement(statement);

至此所有需要的配置已完成,从这里可以看出使用注解配置SQL的方式核心在于将原来从Mapper.xml解析封装MappedStatment对象的方式,改为从使用注解的方法上进行解析封装MappedStatment对象,之后的过程与前面两种调用方式相同,不再赘述。

相关参考

MyBatis源码分析——MyBatis核心组件和开启SqlSession
MyBatis源码分析——使用SqlSession操作数据库
MyBatis源码分析——调用Mapper接口方法执行SQL
MyBatis源码分析——使用注解执行SQL

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值