过一遍mybatis源码-1

Posted 叔叔的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了过一遍mybatis源码-1相关的知识,希望对你有一定的参考价值。

先过一遍mybatis的简单介绍和使用。
http://www.mybatis.org/mybatis-3/zh/getting-started.html

比较好的mybatis源码解析 https://blog.csdn.net/nmgrd/article/details/54608702

这么好的框架,自己撸一遍收获会很大。

我看的是这位大牛翻译的源码 https://github.com/tuguangquan/mybatis.git

先分析初始化过程。(暂时只分析xml配置方式)

从这段开始看。

@Test
public void test() throws IOException {
   InputStream inputStream = Resources.getResourceAsStream("resources/mybatis-config.xml");
   SqlSessionFactory build = new SqlSessionFactoryBuilder().build(inputStream);
   SqlSession sqlSession = build.openSession();
   Object result = sqlSession.selectOne("select * from user");
}

一、读取配置文件

InputStream inputStream = Resources.getResourceAsStream("resources/mybatis-config.xml");

主要是加载5个类加载器去查找资源

//一共5个类加载器
ClassLoader[] getClassLoaders(ClassLoader classLoader) {
   return new ClassLoader[]{
           classLoader,
           defaultClassLoader,
           Thread.currentThread().getContextClassLoader(),
           getClass().getClassLoader(),
           systemClassLoader};
}

二、创建SqlSessionFactory

SqlSessionFactory build = new SqlSessionFactoryBuilder().build(inputStream);

这步就是mybatis的初始化。

 public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
       XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
       return build(parser.parse());
   }

会创建XMLConfigBuilder

 //上面6个构造函数最后都合流到这个函数,传入XPathParser
 private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
   //首先调用父类初始化Configuration
   super(new Configuration());
   //错误上下文设置成SQL Mapper Configuration(XML文件配置),以便后面出错了报错用吧
   ErrorContext.instance().resource("SQL Mapper Configuration");
   //将Properties全部设置到Configuration里面去
   this.configuration.setVariables(props);
   this.parsed = false;
   this.environment = environment;
   this.parser = parser;
 }
 ```
 这里configuration会注册一些类型别名。
 然后parser.parse()解析节点,根节点是/configuration。
 ```
 //  <?xml version="1.0" encoding="UTF-8" ?>
//  <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
//  "http://mybatis.org/dtd/mybatis-3-config.dtd">

//  <configuration>
//  <environments default="development">
//  <environment id="development">
//  <transactionManager type="JDBC"/>
//  <dataSource type="POOLED">
//  <property name="driver" value="${driver}"/>
//  <property name="url" value="${url}"/>
//  <property name="username" value="${username}"/>
//  <property name="password" value="${password}"/>
//  </dataSource>
//  </environment>
//  </environments>
//  <mappers>
//  <mapper resource="org/mybatis/example/BlogMapper.xml"/>
//  </mappers>
//  </configuration>

对这些node进行解析,塞到configuration中。

解析完后,进行build,返回DefaultSqlSessionFactory。

三、生成SqlSession

  private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
   Transaction tx = null;
   try {
     final Environment environment = configuration.getEnvironment();
     final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
     //通过事务工厂来产生一个事务
     tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
     //生成一个执行器(事务包含在执行器里)
     final Executor executor = configuration.newExecutor(tx, execType);
     //然后产生一个DefaultSqlSession
     return new DefaultSqlSession(configuration, executor, autoCommit);
   } catch (Exception e) {
     //如果打开事务出错,则关闭它
     closeTransaction(tx); // may have fetched a connection so lets call close()
     throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
   } finally {
     //最后清空错误上下文
     ErrorContext.instance().reset();
   }
 }

第一步生成事务

第二步生成执行器,这里会选择一种执行器,另外,会调用插件,通过插件可以改变Executor行为。

第三步,return new DefaultSqlSession(configuration, executor, autoCommit);

这样sqlSession就生成了。

四、总结

初始化还算思路简单清晰。

这里用到的设计模式有,工厂,单例,构造者模式,拓展性强。

第一天代码放在了 https://coding.net/u/unclehh/p/mybatis-review/git/tree/day-1?public=true


以上是关于过一遍mybatis源码-1的主要内容,如果未能解决你的问题,请参考以下文章

Koa源码分析

#yyds干货盘点# mybatis源码解读:executor包(语句处理功能)

AQS简简单单过一遍

MyBatis源码解读——MapperMethod

Springboot系列之Springboot与Mybatis整合

Mybatis+SpringMVC实现分页查询(附源码)