美文网首页
mybatis原理

mybatis原理

作者: laowangv2 | 来源:发表于2020-12-20 22:12 被阅读0次

mybatis的运行流程

一、原生用法

1. 构建SqlSessionFactory

String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

在SqlSessionFactoryBuilder中,首先解析配置文件,得到Configuration,然后build new一个SqlSessionFactory返回:


build

看一下parse中具体做了哪些工作:


parse
mapperElement中会把解析出来的Mapper放到MapperRegistry中,以便后续使用。

2. 创建SqlSession

try (SqlSession session = sqlSessionFactory.openSession()) {
  Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);
}

最终委托到DefaultSqlSessionFactory的openSessionFromDataSource:


创建SqlSession

之后,一个集齐了executor,configuration的SqlSession就创建好了。

3. 创建Mapper

看一下SqlSession里getMapper的具体实现:


getMapper

委托给configuration后又委托给了mapperRegistry:


mapperRegistry
在第一步创建SqlSessionFactory的最后说过,在parse中会解析xml中的mapper并放入mapperRegistry中,现在就是取出来构建实例的时候了。并且传入了sqlSession,这样后续mapper中就可以把具体操作委托给sqlSession去完成。
MapperProxyFactory
MapperProxy

接着就可以看到这里到了真正创建Mapper的时机,也看到Mapper的实现类MapperProxy,通过动态代理的方式创建出来。我们知道动态代理最终的方法会委托给InvocationHandler里,进到MapperProxy看一下,果不其然:


MapperProxy
最后在mapperMethod中,不出意外肯定会委托给sqlSession执行:
MapperMethod
好了,先到这里,后续在分析在SqlSession中的执行过程。

二、让Spring管理一切

1. SqlSessionFactoryBean

把SqlSessionFactory注入到spring容器中

@Configuration
public class MyBatisConfig {
  @Bean
  public SqlSessionFactory sqlSessionFactory() {
    SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
    factoryBean.setDataSource(dataSource());
    return factoryBean.getObject();
  }
}

2. SqlSession同理

@Configuration
public class MyBatisConfig {
  @Bean
  public SqlSessionTemplate sqlSession() throws Exception {
    return new SqlSessionTemplate(sqlSessionFactory());
  }
}

现在已经获得了和原生用法中一样的效果,并且更进一步,可以以注入的方式使用SqlSession了。

3. Mapper

实际使用中,显然不可能通过SqlSessionTemplate一个一个去getMapper,都是通过spring管理,直接注入使用。那么必然有地方把Mapper都加载起来纳入Spring管理。以@MapperScan为例分析其过程如下。

MapperScannerRegistrar
在MapperScannerRegistrar中,借助spring的能力扫描满足条件的mapper,并将其注入容器。具体参考https://blog.csdn.net/elim168/article/details/88131712
doScan
到这里已经可以看到,往spring容器里注入了mapper,class是MapperFactoryBean,对于FactoryBean,spring创建bean的时候会调用其getObject方法,进入MapperFactoryBean看一下
MapperFactoryBean
Ok,这样就和原生用法中的分析一致,回到了SqlSession的getMapper。
一路看下来,我们可以看出来,引入spring-mybatis,其实就是把原来需要我们手动去操作mybatis的地方全部以spring的方式管理起来,我们只管用注入的方式去使用Mapper就好了。

三、SqlSession如何操作数据库

select
MapperStatement从configuration中获取,最初在解析xml的时候会一并解析存入。
然后交给executor执行,executor出现在openSessionFromDataSource时,默认类型是SimpleExecutor。继续跟踪,进入到基类BaseExecutor中:
BaseExecutor
首先从cache中提取,如果没有就进入queryFromDatabase,queryFromDatabase中又回到了Executor实现类的doQuery:
doQuery
在newStatementHandler中会把plugin插进去,prepareStatement会拿到一个connection,并编译statement,也就是使用jdbc时需要的那些操作,最后交由handler执行:
PreparedStatementHandler
这里默认的就是PreparedStatementHandler,也就是预编译PreparedStatement。

mybatis架构

mybatis主要构件

对照图2


mybatis架构设计

参考
深入理解mybatis原理

相关文章

网友评论

      本文标题:mybatis原理

      本文链接:https://www.haomeiwen.com/subject/pvmknktx.html