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

文章目录

  • MyBatis源码分析
    • 使用注解方式执行SQL
    • 相关参考

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类中。
MyBatis源码分析——使用注解执行SQL_第1张图片
在MapperAnnotationBuilder类中有个parse()方法用于对使用注解的Mapper接口方法进行解析转换,parse()方法源码如下:
MyBatis源码分析——使用注解执行SQL_第2张图片
从源码中可以看到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

你可能感兴趣的:(MyBatis,数据库,Java)