博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
解析生成MappedStatement
阅读量:2155 次
发布时间:2019-05-01

本文共 8915 字,大约阅读时间需要 29 分钟。

功能

就是把1条<select></select> 或 <insert/> 等变成1个MappedStatement

相关类

XMLConfigBuilder

解析mybatis-config.xml

XMLMapperBuilder

解析具体的mapper.xml,比如AccountMapper.xml

XMLStatementBuilder

解析xml文件中各个节点,比如<select/>、<insert/>、<update/>、<delete/>节点

MapperAnnotationBuilder

注解处理(Select、Insert、Update、Delete等)

spring-mybatis方式

SqlSessionFactoryBean

protected SqlSessionFactory buildSqlSessionFactory() throws Exception {......................// 如果配置了mybatis.mapper-locationsif (this.mapperLocations != null) {      if (this.mapperLocations.length == 0) {        LOGGER.warn(() -> "Property 'mapperLocations' was specified but matching resources are not found.");      } else {        for (Resource mapperLocation : this.mapperLocations) {          if (mapperLocation == null) {            continue;          }          try {            XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),                targetConfiguration, mapperLocation.toString(), targetConfiguration.getSqlFragments());            xmlMapperBuilder.parse();          } catch (Exception e) {            throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);          } finally {            ErrorContext.instance().reset();          }          LOGGER.debug(() -> "Parsed mapper file: '" + mapperLocation + "'");        }      }    }......................}

 

xml方式

XMLStatementBuilder

解析xml文件中各个节点,比如<select/>、<insert/>、<update/>、<delete/>节点,内部会使用XMLScriptBuilder处理节点的sql部分,

每个节点(<select/>、<insert/>、<update/>、<delete/>)会生成1个MappedStatement,然后会放到Configuration的mappedStatements中

 

添加Mapper

private void bindMapperForNamespace() {    String namespace = builderAssistant.getCurrentNamespace();    if (namespace != null) {      Class
boundType = null; try { boundType = Resources.classForName(namespace); } catch (ClassNotFoundException e) { //ignore, bound type is not required } if (boundType != null) { if (!configuration.hasMapper(boundType)) { // Spring may not know the real resource name so we set a flag // to prevent loading again this resource from the mapper interface // look at MapperAnnotationBuilder#loadXmlResource configuration.addLoadedResource("namespace:" + namespace); configuration.addMapper(boundType); //添加Mapper } } } }

 

MapperRegistry

public 
void addMapper(Class
type) { if (type.isInterface()) { if (hasMapper(type)) { throw new BindingException("Type " + type + " is already known to the MapperRegistry."); } boolean loadCompleted = false; try { knownMappers.put(type, new MapperProxyFactory<>(type)); // It's important that the type is added before the parser is run // otherwise the binding may automatically be attempted by the // mapper parser. If the type is already known, it won't try. MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type); parser.parse(); loadCompleted = true; } finally { if (!loadCompleted) { knownMappers.remove(type); } } } }

 

MappedStatement

public final class MappedStatement {  private String resource; // file [E:\zyzhworkspace\springboot2\database\mybatis\mybatis-mapper\target\classes\com\kq\mybatis\mapper\AccountXmlMapper.xml]  private Configuration configuration;  private String id;  private Integer fetchSize;  private Integer timeout;  private StatementType statementType; //STATEMENT, PREPARED, CALLABLE  private ResultSetType resultSetType;  private SqlSource sqlSource;  private Cache cache;  private ParameterMap parameterMap;  private List
resultMaps; private boolean flushCacheRequired; private boolean useCache; private boolean resultOrdered; private SqlCommandType sqlCommandType; // UNKNOWN, INSERT, UPDATE, DELETE, SELECT, FLUSH; private KeyGenerator keyGenerator; private String[] keyProperties; private String[] keyColumns; private boolean hasNestedResultMaps; private String databaseId; private Log statementLog; private LanguageDriver lang; private String[] resultSets;}

MapperBuilderAssistant

addMappedStatement

public MappedStatement addMappedStatement(..........................MappedStatement statement = statementBuilder.build();    configuration.addMappedStatement(statement); // 放到configuration mappedStatements.put(ms.getId(), ms);// id比如: com.kq.mybatis.mapper.AccountXmlMapper.getAccountList    return statement;}

 

注解方式

MapperAnnotationBuilder

解析注解(Select、Insert、Update、Delete)生成1个MappedStatement,然后会放到Configuration的mappedStatements中

parse

public void parse() {    String resource = type.toString();    if (!configuration.isResourceLoaded(resource)) {      loadXmlResource(); // 从xml加载,有可能没有xml的mapper文件的      configuration.addLoadedResource(resource); // hashset 不会重复添加      assistant.setCurrentNamespace(type.getName()); // 设置namespace      parseCache();      parseCacheRef();      Method[] methods = type.getMethods(); // 获得方法      for (Method method : methods) {        try {          // issue #237          if (!method.isBridge()) {            parseStatement(method);          }        } catch (IncompleteElementException e) {          configuration.addIncompleteMethod(new MethodResolver(this, method));        }      }    }    parsePendingMethods();  }

parseStatement 

void parseStatement(Method method) {    Class
parameterTypeClass = getParameterType(method); LanguageDriver languageDriver = getLanguageDriver(method); SqlSource sqlSource = getSqlSourceFromAnnotations(method, parameterTypeClass, languageDriver); if (sqlSource != null) { Options options = method.getAnnotation(Options.class); final String mappedStatementId = type.getName() + "." + method.getName(); // 比如: com.kq.mybatis.mapper.AccountMapper.getAccountList Integer fetchSize = null; Integer timeout = null; StatementType statementType = StatementType.PREPARED; ResultSetType resultSetType = configuration.getDefaultResultSetType(); SqlCommandType sqlCommandType = getSqlCommandType(method); boolean isSelect = sqlCommandType == SqlCommandType.SELECT; boolean flushCache = !isSelect; boolean useCache = isSelect; KeyGenerator keyGenerator; String keyProperty = null; String keyColumn = null; if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)) { // first check for SelectKey annotation - that overrides everything else SelectKey selectKey = method.getAnnotation(SelectKey.class); if (selectKey != null) { keyGenerator = handleSelectKeyAnnotation(selectKey, mappedStatementId, getParameterType(method), languageDriver); keyProperty = selectKey.keyProperty(); } else if (options == null) { keyGenerator = configuration.isUseGeneratedKeys() ? Jdbc3KeyGenerator.INSTANCE : NoKeyGenerator.INSTANCE; } else { keyGenerator = options.useGeneratedKeys() ? Jdbc3KeyGenerator.INSTANCE : NoKeyGenerator.INSTANCE; keyProperty = options.keyProperty(); keyColumn = options.keyColumn(); } } else { keyGenerator = NoKeyGenerator.INSTANCE; // 没有KeyGenerator 排除Insert和Update } if (options != null) { if (FlushCachePolicy.TRUE.equals(options.flushCache())) { flushCache = true; } else if (FlushCachePolicy.FALSE.equals(options.flushCache())) { flushCache = false; } useCache = options.useCache(); fetchSize = options.fetchSize() > -1 || options.fetchSize() == Integer.MIN_VALUE ? options.fetchSize() : null; //issue #348 timeout = options.timeout() > -1 ? options.timeout() : null; statementType = options.statementType(); if (options.resultSetType() != ResultSetType.DEFAULT) { resultSetType = options.resultSetType(); } } String resultMapId = null; // 比如: com.kq.mybatis.mapper.AccountMapper.getAccountList-void ResultMap resultMapAnnotation = method.getAnnotation(ResultMap.class); if (resultMapAnnotation != null) { resultMapId = String.join(",", resultMapAnnotation.value()); } else if (isSelect) { resultMapId = parseResultMap(method); } 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); } }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载地址:http://bexwb.baihongyu.com/

你可能感兴趣的文章
行为型模式之模板方法模式(TemplateMethod)
查看>>
行为型模式之访问者模式(Visitor)
查看>>
大小端详解
查看>>
source insight使用方法简介
查看>>
<stdarg.h>头文件的使用
查看>>
C++/C 宏定义(define)中# ## 的含义 宏拼接
查看>>
Git安装配置
查看>>
linux中fork()函数详解
查看>>
C语言字符、字符串操作偏僻函数总结
查看>>
Git的Patch功能
查看>>
分析C语言的声明
查看>>
TCP为什么是三次握手,为什么不是两次或者四次 && TCP四次挥手
查看>>
C结构体、C++结构体、C++类的区别
查看>>
进程和线程的概念、区别和联系
查看>>
CMake 入门实战
查看>>
绑定CPU逻辑核心的利器——taskset
查看>>
Linux下perf性能测试火焰图只显示函数地址不显示函数名的问题
查看>>
c结构体、c++结构体和c++类的区别以及错误纠正
查看>>
Linux下查看根目录各文件内存占用情况
查看>>
A星算法详解(个人认为最详细,最通俗易懂的一个版本)
查看>>