关于动态 SQL 的接口和类
关于动态 SQL 的接口和类
SqlNode 接口,简单理解就是 xml 中的每个标签,比如上述 sql 的 update,trim,if 标签:
public interface SqlNode {
boolean apply(DynamicContext context);
}
SqlSource Sql 源接口,代表从 xml 文件或注解映射的 sql 内容,主要就是用于创建 BoundSql,有实现类 DynamicSqlSource (动态 Sql 源),StaticSqlSource (静态 Sql 源) 等:
public interface SqlSource {
BoundSql getBoundSql(Object parameterObject);
}
BoundSql 类,封装 mybatis 最终产生 sql 的类,包括 sql 语句,参数,参数源数据等参数:
XNode,一个 Dom API 中的 Node 接口的扩展类:
BaseBuilder 接口及其实现类 (属性,方法省略了,大家有兴趣的自己看), 这些 Builder 的作用就是用于构造 sql:
下面我们简单分析下其中 4 个 Builder:
-
XMLConfigBuilder:解析 mybatis 中 configLocation 属性中的全局 xml 文件,内部会使用 XMLMapperBuilder 解析各个 xml 文件。 XMLMapperBuilder:遍历 mybatis 中 mapperLocations 属性中的 xml 文件中每个节点的 Builder,比如 user.xml,内部会使用 XMLStatementBuilder 处理 xml 中的每个节点。 XMLStatementBuilder:解析 xml 文件中各个节点,比如 select,insert,update,delete 节点,内部会使用 XMLScriptBuilder 处理节点的 sql 部分,遍历产生的数据会丢到 Configuration 的 mappedStatements 中。 XMLScriptBuilder:解析 xml 中各个节点 sql 部分的 Builder。
LanguageDriver 接口及其实现类 (属性,方法省略了,大家有兴趣的自己看),该接口主要的作用就是构造 sql:
简单分析下 XMLLanguageDriver (处理 xml 中的 sql,RawLanguageDriver 处理静态 sql):XMLLanguageDriver 内部会使用 XMLScriptBuilder 解析 xml 中的 sql 部分。
源码分析走起
Spring 与 Mybatis 整合的时候需要配置 SqlSessionFactoryBean,该配置会加入数据源和 mybatis xml 配置文件路径等信息:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:mybatisConfig.xml"/> <property name="mapperLocations" value="classpath*:org/format/dao/*.xml"/> </bean>
我们就分析这一段配置背后的细节:
SqlSessionFactoryBean 实现了 Spring 的 InitializingBean 接口,InitializingBean 接口的 afterPropertiesSet 方法中会调用 buildSqlSessionFactory 方法 该方法内部会使用 XMLConfigBuilder 解析属性 configLocation 中配置的路径,还会使用 XMLMapperBuilder 属性解析 mapperLocations 属性中的各个 xml 文件。部分源码如下:
由于 XMLConfigBuilder 内部也是使用 XMLMapperBuilder,我们就看看 XMLMapperBuilder 的解析细节:
XMLStatementBuilder 的解析:
默认会使用 XMLLanguageDriver 创建 SqlSource(Configuration 构造函数中设置)。
