mybatis 分析
jdbc
jdbc 主要作用是获取数据源,获得查询结果。存在的问题是需要手写 sql,对结果集处理麻烦,mybatis 主要解决这个两个问题
// 1.加载类,并注册驱动器(Driver会注册到DriverManager中) Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); // 2.根据特定的URL,返回可以接受此URL的数据库驱动对象 Driver driver = DriverManager.getDriver(URL); // 3.使用数据库驱动创建数据库连接Connection会话 connection = driver.connect(URL, props); // 4.获得Statement对象 statement = connection.createStatement(); // 5.执行 sql语句,返回结果 resultSet = statement.executeQuery("select * from emp");
mybatis 解析
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.xx.dao"/> <property name="sqlSessionFactoryBeanName" value="sessionFactory"/> <property name="annotationClass" "value=""com.selfdefine.MyDataSource"/> </bean>
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { if (this.processPropertyPlaceHolders) { processPropertyPlaceHolders(); } ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry); scanner.setAddToConfig(this.addToConfig); scanner.setAnnotationClass(this.annotationClass); scanner.setMarkerInterface(this.markerInterface); scanner.setSqlSessionFactory(this.sqlSessionFactory); scanner.setSqlSessionTemplate(this.sqlSessionTemplate); scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName); scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName); scanner.setResourceLoader(this.applicationContext); scanner.setBeanNameGenerator(this.nameGenerator); scanner.registerFilters(); scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS)); }
MapperFactoryBean 子类实现,下面分析 addMapper 方法
最终生成 MappedStatement,放入 configuration 中,待查询时使用
MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType) .resource(resource) .fetchSize(fetchSize) .timeout(timeout) .statementType(statementType) .keyGenerator(keyGenerator) .keyProperty(keyProperty) .keyColumn(keyColumn) .databaseId(databaseId) .lang(lang) .resultOrdered(resultOrdered) .resultSets(resultSets) .resultMaps(getStatementResultMaps(resultMap, resultType, id)) .resultSetType(resultSetType) .flushCacheRequired(valueOrDefault(flushCache, !isSelect)) .useCache(valueOrDefault(useCache, isSelect)) .cache(currentCache); ParameterMap statementParameterMap = getStatementParameterMap(parameterMap, parameterType, id); if (statementParameterMap != null) { statementBuilder.parameterMap(statementParameterMap); } MappedStatement statement = statementBuilder.build(); configuration.addMappedStatement(statement);
mybatis 查询
最终拿到 MappedStatement 对象,进行结果解析
解析的过程没什么好说的,最重要的是类型匹配。TypeHandlerRegistry 在程序启动时,会注入默认处理器,并会根据配置信息,注入用户自定义处理器