Mybatis动态解析sql 我们在使⽤mybatis的时候,会在xml中编写sql语句,⽐如这段动态sql代码:
<update id="update" parameterType="org.batis.bean.User">
UPDATE users
<trim prefix="SET" prefixOverrides=",">
<if test="name != null and name != ''">
name = #{name}
</if>
<if test="age != null and age != ''">
, age = #{age}
</if>
<if test="birthday != null and birthday != ''">
,
birthday = #{birthday}
</if>
</trim>
where id = ${id}
</update>
mybatis底层是如何构造这段sql的?
这⽅⾯的知识⽹上资料不多,于是就写了这么⼀篇⽂章。
下⾯带着这个疑问,我们⼀步⼀步分析。
介绍MyBatis中⼀些关于动态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语句,参数,参数源数据等参数:
sql中update什么意思
XNode,⼀个Dom API中的Node接⼝的扩展类。
BaseBuilder接⼝及其实现类(属性,⽅法省略了,⼤家有兴趣的⾃⼰看),这些Builder的作⽤就是⽤于构造sql:
下⾯我们简单分析下其中4个Builder:
1 XMLConfigBuilder
解析mybatis中configLocation属性中的全局xml⽂件,内部会使⽤XMLMapperBuilder解析各个xml⽂件。
2 XMLMapperBuilder
遍历mybatis中mapperLocations属性中的xml⽂件中每个节点的Builder,⽐如l,内部会使⽤XMLStatementBuilder处理xml 中的每个节点。
3 XMLStatementBuilder
解析xml⽂件中各个节点,⽐如select,insert,update,delete节点,内部会使⽤XMLScriptBuilder处理节点的sql部分,遍历产⽣的数据会丢到Configuration的mappedStatements中。
4 XMLScriptBuilder
解析xml中各个节点sql部分的Builder。
LanguageDriver接⼝及其实现类(属性,⽅法省略了,⼤家有兴趣的⾃⼰看),该接⼝主要的作⽤就是构造sql:
简单分析下XMLLanguageDriver(处理xml中的sql,RawLanguageDriver处理静态sql):
XMLLanguageDriver内部会使⽤XMLScriptBuilder解析xml中的sql部分。
ok, ⼤部分⽐较重要的类我们都已经介绍了,下⾯源码分析⾛起。
源码分析⾛起
Spring与Mybatis整合的时候需要配置SqlSessionFactoryBean,该配置会加⼊数据源和mybatis xml配置⽂件路径等信息:
<bean id="sqlSessionFactory" class="batis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="l"/>
<property name="mapperLocations" value="classpath*:org/format/dao/*.xml"/>
</bean>
我们就分析这⼀段配置背后的细节:
SqlSessionFactoryBean实现了Spring的InitializingBean接⼝,InitializingBean接⼝的afterPropertiesSet⽅法中会调⽤buildSqlSessionFactory⽅法
buildSqlSessionFactory⽅法内部会使⽤XMLConfigBuilder解析属性configLocation中配置的路径,还会使⽤XMLMapperBuilder属性解析mapperLocations属性中的各个xml⽂件。
部分源码如下:
由于XMLConfigBuilder内部也是使⽤XMLMapperBuilder,我们就看看XMLMapperBuilder的解析细节。
我们关注⼀下,增删改查节点的解析。
XMLStatementBuilder的解析:
默认会使⽤XMLLanguageDriver创建SqlSource(Configuration构造函数中设置)。
XMLLanguageDriver创建SqlSource:
XMLScriptBuilder解析sql:
得到SqlSource之后,会放到Configuration中,有了SqlSource,就能拿BoundSql了,BoundSql可以得到最终的sql。实例分析
我以以下xml的解析⼤概说下parseDynamicTags的解析过程:
<update id="update" parameterType="org.batis.bean.User">
UPDATE users
<trim prefix="SET" prefixOverrides=",">
<if test="name != null and name != ''">
name = #{name}
</if>
<if test="age != null and age != ''">
, age = #{age}
</if>
<if test="birthday != null and birthday != ''">
, birthday = #{birthday}
</if>
</trim>
where id = ${id}
</update>
在看这段解析之前,请先了解dom相关的知识,,

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。