三、mybatis实现与集成缓存

230 阅读1分钟

一、执行流程解析


知识点

  1. 配置文件解析(Configuration)
  2. 会话创建(SqlSession)
  3. 方法执行(StatementHandler)

1、配置文件解析(Configuration)

mybatis-config.xml中配置文件的结构:

<configuration>

    <properties resource="jdbc.properties"></properties>

    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <environments default="${default.environment}">
        <environment id="dev">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <package name="com.cyan.mybatis.dao"/>
    </mappers>
</configuration>

mybatis-mapper.xml中配置文件的结构:

<mapper namespace="com.cyan.mybatis.dao.UserMapper">
    <!--<cache/>-->
    <select id="updateUserById1" parameterType="com.cyan.mybatis.pojo.User">
        update user set name = #{name} where id = #{id}
    </select>
</mapper>

配置文件的解析流程即是将上述XML描述元素转换成对应的JAVA对象过程,其最终转换对象及其关系如图所示:

配置元素解析构建器:

> org.apache.ibatis.builder.xml.XMLConfigBuilder
> org.apache.ibatis.builder.xml.XMLMapperBuilder
> org.apache.ibatis.builder.xml.XMLStatementBuilder
> org.apache.ibatis.builder.SqlSourceBuilder
> org.apache.ibatis.scripting.xmltags.XMLScriptBuilder
> org.apache.ibatis.builder.annotation.MapperAnnotationBuilder

构建流程源码

> org.apache.ibatis.session.SqlSessionFactoryBuilder#build()
# 1.Config.xml 文件解析
> org.apache.ibatis.builder.xml.XMLConfigBuilder#parse()
> org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration()
> org.apache.ibatis.builder.xml.XMLConfigBuilder#mapperElement()

# 2.Mapper.xml 文件解析
> org.apache.ibatis.builder.xml.XMLMapperBuilder#parse()
> org.apache.ibatis.builder.xml.XMLMapperBuilder#configurationElement()
> org.apache.ibatis.builder.xml.XMLMapperBuilder#buildStatementFromContext()

# 3.Statemen sql块解析
> org.apache.ibatis.builder.xml.XMLStatementBuilder#parseStatementNode()

# 4.动态SQL脚本解析
> org.apache.ibatis.scripting.xmltags.XMLLanguageDriver#createSqlSource()
> org.apache.ibatis.scripting.xmltags.XMLScriptBuilder#parseScriptNode()
> org.apache.ibatis.scripting.xmltags.XMLScriptBuilder#parseDynamicTags()

> org.apache.ibatis.builder.MapperBuilderAssistant#addMappedStatement()
> org.apache.ibatis.session.Configuration#addMappedStatement()

2、会话创建(SqlSession)

会话对像的组成结构如图所示:

会话构建源码分析

> org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSession(boolean)
> org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSessionFromDataSource()
> org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory#newTransaction()
> org.apache.ibatis.session.Configuration#newExecutor()
> org.apache.ibatis.executor.SimpleExecutor#SimpleExecutor
> org.apache.ibatis.executor.CachingExecutor#CachingExecutor

# 执行器插件包装
> org.apache.ibatis.plugin.InterceptorChain#pluginAll(executor)
> org.apache.ibatis.session.defaults.DefaultSqlSession#DefaultSqlSession()

3、方法执行(StatementHandler)

StatementHandler源码分析

> org.apache.ibatis.session.defaults.DefaultSqlSession#selectList()
> org.apache.ibatis.executor.CachingExecutor#query()
> org.apache.ibatis.executor.BaseExecutor#query()
> org.apache.ibatis.executor.BaseExecutor#queryFromDatabase()
> org.apache.ibatis.executor.SimpleExecutor#doQuery()
> org.apache.ibatis.session.Configuration#newStatementHandler()
> org.apache.ibatis.executor.statement.RoutingStatementHandler#RoutingStatementHandler()
> org.apache.ibatis.executor.statement.BaseStatementHandler#BaseStatementHandler()
> org.apache.ibatis.session.Configuration#newParameterHandler()
> org.apache.ibatis.plugin.InterceptorChain#pluginAll(parameterHandler)

> org.apache.ibatis.session.Configuration#newResultSetHandler()
> org.apache.ibatis.plugin.InterceptorChain#pluginAll(resultSetHandler)

> org.apache.ibatis.plugin.InterceptorChain#pluginAll(statementHandler)

> org.apache.ibatis.executor.SimpleExecutor#prepareStatement()
> org.apache.ibatis.executor.BaseExecutor#getConnection()
> org.apache.ibatis.executor.statement.BaseStatementHandler#prepare()
> org.apache.ibatis.executor.statement.PreparedStatementHandler#instantiateStatement()

> org.apache.ibatis.executor.statement.PreparedStatementHandler#parameterize()
> org.apache.ibatis.scripting.defaults.DefaultParameterHandler#setParameters()
> org.apache.ibatis.type.BaseTypeHandler#setParameter()
> org.apache.ibatis.type.UnknownTypeHandler#setNonNullParameter()

> org.apache.ibatis.type.IntegerTypeHandler#setNonNullParameter()

二、mybatis插件开发


知识点

  1. 插件的四大扩展点
  2. 分页插件实现

1、插件的四大扩展点

  1. Executor
  2. StatementHandler
  3. ParameterHandler
  4. ResultSetHandler

2、分页插件实现

用户在接口中声明Page对象实现后,由插件实现自动分页。使用示例如下:

Page对象属性声明

public class Page implements Serializable {
    private Integer size;//每页大小
    private Integer number;//当前页码
}    

page参数声明

@Select("select * from user")
List<User> selectUserListByPage(Page page);

客户端调用

UserMapper $proxy = session.getMapper(UserMapper.class);
List<User> userList = $proxy.selectUserListByPage(new Page(5,2));

实现目标分解:

  1. 修改SQL并添加limit语句
  2. 判断方法参数中是否有Page对象
  3. 取出Page对象生成limit语句
  4. 上述操作必须在PreparedStatement对象生成前完成