mybatis源码学习之——内部处理流程

接下来,我们按照之前写的测试用例,使用debug来梳理一下mybatis的工作流程,测试用例如下:

package com.mybatis.mine;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.InputStream;

public class MineTest1 {

    @Test
    public void test01() throws IOException {
      String resource = "com/mybatis/mine/mybatis-config.xml";
      InputStream inputStream = Resources.getResourceAsStream(resource);
      SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
      SqlSession sqlSession = sqlSessionFactory.openSession();
      UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
      User user = userMapper.selectUser("10");
      System.out.println(user);
    }
}

首先我们来跟踪SqlSessionFactory的创建:SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

经过debug跟踪,我们会发现这个流程的主要步骤如下:

org.apache.ibatis.session.SqlSessionFactoryBuilder#build(java.io.InputStream)    //使用SqlSessionFactoryBuilder的build
   >org.apache.ibatis.session.SqlSessionFactoryBuilder#build(java.io.InputStream, java.lang.String, java.util.Properties) 
          >org.apache.ibatis.builder.xml.XMLConfigBuilder#parse    //加载配置文件,获取configuration对象
             >org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration
                 >org.apache.ibatis.builder.xml.XMLConfigBuilder#mapperElement  //加载映射器
                     >org.apache.ibatis.session.Configuration#addMapper
                       >org.apache.ibatis.binding.MapperRegistry#addMapper
                           >org.apache.ibatis.builder.annotation.MapperAnnotationBuilder#parse   //Annotation方式解析
    >org.apache.ibatis.session.SqlSessionFactoryBuilder#build(org.apache.ibatis.session.Configuration)    //生成SqlSessionFactory

也就是说在这里,mybatis主要做了加载配置文件、加载映射器、生成SqlSessionFactory等主要操作。

接下来我们来SqlSession的获取:SqlSession sqlSession = sqlSessionFactory.openSession();

org.apache.ibatis.session.SqlSessionFactory#openSession()   //获取SqlSession
    >org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSessionFromDataSource     
        >org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#getTransactionFactoryFromEnvironment   //获取 TransactionFactory
            >org.apache.ibatis.transaction.TransactionFactory#newTransaction(javax.sql.DataSource, org.apache.ibatis.session.TransactionIsolationLevel, boolean)   //获取事务
                >org.apache.ibatis.session.Configuration#newExecutor(org.apache.ibatis.transaction.Transaction, org.apache.ibatis.session.ExecutorType)  // 生成Executor
                    >org.apache.ibatis.session.defaults.DefaultSqlSession   //new DefaultSqlSession() 

对于这一步,mybatis主要做的工作就是生成事务、创建执行器、最后生成SqlSession实例

对于UserMapper userMapper = sqlSession.getMapper(UserMapper.class);我们就不多赘述了,这个主要是从第一步的MapperRegistry中获取相应的Mapper

最后我们来看下具体的数据库操作流程:

org.apache.ibatis.binding.MapperProxy#invoke    //动态代理
    >org.apache.ibatis.binding.MapperMethod#execute
       >org.apache.ibatis.session.SqlSession#selectOne(java.lang.String, java.lang.Object)    //进行查询
          >org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
             >org.apache.ibatis.session.Configuration#getMappedStatement(java.lang.String)  //获取MappedStatement
                >org.apache.ibatis.session.defaults.DefaultSqlSession#wrapCollection    //解析参数
                   >org.apache.ibatis.executor.BaseExecutor#query()  //真正的查询处理
                      >org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
                          >org.apache.ibatis.executor.BaseExecutor#doQuery
                              >org.apache.ibatis.session.Configuration#newStatementHandler   //生成StatementHandler
                                  >org.apache.ibatis.executor.statement.StatementHandler#query  //使用StatementHandler进行查询处理
                                     >java.sql.PreparedStatement#execute   //调用jdbc的execute方法
                                     >org.apache.ibatis.executor.resultset.ResultSetHandler#handleResultSets   //结果集处理

这一步mybatis首先通过动态代理,找到目标方法,然后使用相应的执行器进行数据库操作。在这一步中做了几点重要的处理:

  • 获取目标方法
  • 生成MappedStatement
  • 装载参数
  • 生成StatementHandler
  • 调用StatementHandler中相应的方法,进行数据库操作
  • 结果集处理

以上便是mybatis一个完整的处理流程,希望对大家有所启发。下面附两张图大致总结一下以上流程:

第一张图描述了从SqlSessionFactory创建到获取Mapper的一个流程:

第二张图描述了mybatis数据库操作的简易流程:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值