mybatis启动

mybatis

Mybatis 启动流程解析

mybatis分析
上面这篇文章的分析挺好的(主要是图画的好,不会画图,很尴尬,盗几张图)。

从MyBatis代码实现的角度来看,MyBatis的主要的核心部件有以下几个:

  • SqlSessionFactory SqlSession 工厂,全局唯一(单库情况)
  • Configuration MyBatis所有的配置信息都维持在Configuration对象之中。
  • SqlSession 作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能
  • Executor MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护
  • StatementHandler 封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合。
  • ParameterHandler 负责对用户传递的参数转换成JDBC Statement 所需要的参数,
  • ResultSetHandler 负责将JDBC返回的ResultSet结果集对象转换成List类型的集合;
  • TypeHandler 负责java数据类型和jdbc数据类型之间的映射和转换
  • MappedStatement MappedStatement维护了一条

xml启动

mybatis 的启动单独使用时通过一个核心配置xml + n个mapper.xml 的
与 springboot 集成的时候,通常只剩下 n个mapper.xml 了(不用xml也行,但是通常还是会使用xml来定义复杂一点的语句)。
我们还是从xml分析

基础概念
1. SqlSessionFactory
SqlSession 工厂,全局唯一(单数据源的情况下),启动实际上就是构建 SqlSessionFactory(但是配置信息全部在 Configuration)
2. SqlSession
跟数据库交互的操作都是基于这个类(即使是 Dao 接口,也是 getMapper 获取到的动态代理)
3. Configuration
核心配置类,所有 mybatis 相关的配置和解析出来的信息都在这里

入门
使用xml

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

不使用xml

DataSource dataSource = BlogDataSourceFactory.getBlogDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMapper(BlogMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);

上面就是启动,获取 SqlSessionFactory 实例后就可以继续获取 SqlSession 进行数据操作了
数据操作

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

SqlSession session = sqlSessionFactory.openSession();
try {
  BlogMapper mapper = session.getMapper(BlogMapper.class);
  Blog blog = mapper.selectBlog(101);
} finally {
  session.close();
}

上面两种操作方式,通常使用的是第二种,并且这部分操作都会进行封装(跟spring 集成的时候),在业务里面直接获取 Dao 接口进行操作(不需要实现类).

入口分析从 SqlSessionFactoryBuilder 开始

SqlSessionFactoryBuilder

public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
    try {
      XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
      return build(parser.parse());
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
      ErrorContext.instance().reset();
      try {
        reader.close();
      } catch (IOException e) {
        // Intentionally ignore. Prefer previous error.
      }
    }
  }

重点就是这个方法,还有一个重载方法,参数类型是 InputStream,根据 api 构建,就可以猜到 XMLConfigBuilder 经过 parse 后,就是 Configuration 实例了

获取 Configuration 实例后

public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
}

// 构建 SqlSessionFactory ,只是将 Configuration 对象传过来的
public DefaultSqlSessionFactory(Configuration configuration) {
    this.configuration = configuration;
}

可以看到 SqlSessionFactory 的实现就是 DefaultSqlSessionFactory

接下来我们看看解析细节

XMLConfigBuilder

这里的就是就是核心配置文件
示例

<?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>
// 当parse 完成后,返回 configuration,这个类是核心类,有所有的信息
  public Configuration parse() {
    if (parsed) {
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
  }

我们不去细看xml解析语法(在构造这个实例的时候就已经解析成一个 Dom 对象了)
这里重要的是 parseConfiguration(parser.evalNode("/configuration")); ,直接就能猜到是解析 configuration 节点

// 解析 xml 配置文件
  // 解析完成后,所有的信息都在 Configuration 对象上
  private 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值