Mybatis自动装配 spring.factories MybatisAutoConfiguration AutoConfiguredMapperScannerRegistrar----->ImportBeanDefinitionRegistrar registerBeanDefinitions( ClassPathMapperScanner.doScan(StringUtils.toStringArray(packages)) 扫描注解Mapper.class ClassPathBeanDefinitionScanner.doScan this.findCandidateComponents(basePackage) 实例化SqlSessionFactory时,解析XML @Bean SqlSessionFactory new SqlSessionFactoryBean() factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapping/*.xml")) 加载xml factoryBean.getObject() this.afterPropertiesSet() this.buildSqlSessionFactory() 循环并解析所有xml new XMLMapperBuilder new XPathParser this.createDocument(new InputSource(inputStream)); DocumentBuilderFactory.newInstance() factory.newDocumentBuilder() builder.parse(inputSource) 解析成Document xmlMapperBuilder.parse() this.configurationElement(this.parser.evalNode("/mapper")); this.builderAssistant.setCurrentNamespace(namespace); this.cacheRefElement(context.evalNode("cache-ref")); this.cacheElement(context.evalNode("cache")); this.parameterMapElement(context.evalNodes("/mapper/parameterMap")); this.resultMapElements(context.evalNodes("/mapper/resultMap")); this.sqlElement(context.evalNodes("/mapper/sql")); this.buildStatementFromContext(context.evalNodes("select|insert|update|delete")); 解析成MappedStatement new XMLStatementBuilder statementParser.parseStatementNode() langDriver.createSqlSource 创建sql XMLScriptBuilder.parseScriptNode() new DynamicSqlSource 动态sql 包含if,while,${xx}等 new RawSqlSource 非动态sql SqlSourceBuilder.parse() GenericTokenParser.parse() 替换#{xxx} 为问号? new StaticSqlSource 封装成静态SqlSource返回 this.builderAssistant.addMappedStatement new org.apache.ibatis.mapping.MappedStatement.Builder this.getStatementParameterMap statementBuilder.parameterMap(statementParameterMap) statementBuilder.build() MappedStatement this.configuration.addMappedStatement(statement) 添加到configuration的mappedStatements this.bindMapperForNamespace() boundType = Resources.classForName(namespace) 加载Mapper class this.configuration.addMapper(boundType) 注册Mapper this.mapperRegistry.addMapper(type) MapperRegistry this.knownMappers.put(type, new MapperProxyFactory(type)) 添加addMapper,调用的时候getMapper MapperAnnotationBuilder parser = new MapperAnnotationBuilder(this.config, type) 注解方法解释器 parser.parse() this.type.getMethods() 循环解析methodd的注解 this.parseStatement(method) 循环结束 this.sqlSessionFactoryBuilder.build(targetConfiguration) new DefaultSqlSessionFactory(config)-----方法openSession---事务,Executor new DefaultSqlSession @Autowired private UserMapper userMapper; 实例化Controller 实例化Service 实例化Mapper MapperFactoryBean MapperFactoryBean.getObject() this.getSqlSession().getMapper(this.mapperInterface) DefaultSqlSession.configuration.getMapper(type, this); MapperRegistry.mapperRegistry.getMapper(type, sqlSession); MapperProxyFactory.newInstance(sqlSession); this.newInstance(new MapperProxy(sqlSession, this.mapperInterface, this.methodCache)); Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy); 调用Mapper方法 User user = userMapper.selectOne("dd") MapperProxy.invoke(Object proxy, Method method, Object[] args) implements InvocationHandle MapperMethod.execute(this.sqlSession, args) sqlSession.selectOne(this.command.getName(), param) this.sqlSessionProxy.selectOne(statement, parameter) SqlSessionInterceptor.invoke(Object proxy, Method method, Object[] args) SqlSession sqlSession = SqlSessionUtils.getSqlSession(xxx Object result = method.invoke(sqlSession, args) 调用反射方法 sqlSession.commit(true) 看情况执行 SqlSessionUtils.closeSqlSession(xxx 反射方法 DefaultSqlSession.selectOne this.executor.query(ms, this.wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER) CachingExecutor.query( this.delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql) BaseExecutor.query( this.queryFromDatabase( this.doQuery( this.prepareStatement( this.getConnection(statementLog) this.transaction.getConnection() SpringManagedTransaction.openConnection() DataSourceUtils.getConnection(this.dataSource) doGetConnection(dataSource) fetchConnection(dataSource) dataSource.getConnection() new HikariPool(this) 创建线程池 dataSource = new DriverDataSource(jdbcUrl, driverClassName, dataSourceProperties, username, password) StatementHandler.prepare(connection, this.transaction.getTimeout()) StatementHandler.prepare(connection, transactionTimeout) this.instantiateStatement(connection) connection.prepareStatement(sql) StatementHandler.parameterize(stmt) PreparedStatementHandler.query(statement, resultHandler) ps.execute() this.resultSetHandler.handleResultSets(ps) DefaultResultSetHandler ResultSetWrapper rsw = this.getFirstResultSet(stmt) 获取字段属性映射关系 循环记录数 this.handleResultSet(rsw, resultMap, multipleResults, (ResultMapping)null) this.handleRowValues(rsw, resultMap, this.resultHandler, this.rowBounds, (ResultMapping)null) 处理字段值 this.handleRowValuesForSimpleResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping); 分为简单和嵌套 this.getRowValue(rsw, discriminatedResultMap); rowValue = this.createResultObject(rsw, resultMap, lazyLoader, columnPrefix) 各种方式创建 this.applyAutomaticMappings(rsw, resultMap, metaObject, (String)null) || foundValues 应用自动映射 this.createAutomaticMappings(rsw, resultMap, metaObject, columnPrefix); mapping.typeHandler.getResult(rsw.getResultSet(), mapping.column); 调用类型处理器 this.applyPropertyMappings this.applyNestedResultMappings 循环结束 this.localCache.putObject(key, list) 缓存
相互学习,共同进步!