Mybatis学习总结(一)SqlSessionFactory

写给自己的:经过半个月Mybatis的学习,对Mybatis的基本用法有了一定的掌握。但是以往学习其它框架的经历告诉我,学习完后不抓紧总结很快又会忘记,遂从头开始梳理总结一遍。从Mybatis的核心组件入手是有效梳理和总结Mybatis框架的有效路径,这些总结不会深入底层框架的源码,专注于上层接口和类的一些分析,因为本人的开发经验都还很欠缺,过早去纠结源码收获必不多。

Mybatis的核心组件有:SqlSessionFactory、SqlSession、Mapper、TypeHandler。前面对它们的总结主要是集中于使用环节,这个系列将集中于它们比较浅显的创建过程和更加细节性的东西。本系列针对Mybatis3.4.5源码进行阐述。

一、SqlSessionFactory

1、细说SqlSessionFactory创建过程

SqlSessionFactory由SqlSessionFactoryBuilder通过xml配置文件或者Configuration配置类对象产生。

我们通常是通过

 InputStream is = Resources.getResourceAsStream(String baseConfigXmlFilePath);

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is)

这两个步骤获取SqlSessionFactory接口对象

那么其中Mybatis帮我们做了哪些事呢?

首先看SqlSessionFactoryBuilder这个类

public class SqlSessionFactoryBuilder {

  public SqlSessionFactory build(Reader reader) {

    return build(reader, null, null);

  }

  public SqlSessionFactory build(Reader reader, String environment) {

    return build(reader, environment, null);

  }

  public SqlSessionFactory build(Reader reader, Properties properties) {

    return build(reader, null, properties);

  }

  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.

      }

    }

  }

  public SqlSessionFactory build(InputStream inputStream) {

    return build(inputStream, null, null);

  }

  public SqlSessionFactory build(InputStream inputStream, String environment) {

    return build(inputStream, environment, null);

  }

  public SqlSessionFactory build(InputStream inputStream, Properties properties) {

    return build(inputStream, null, properties);

  }

  public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {

    try {

      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);

      return build(parser.parse());

    } catch (Exception e) {

      throw ExceptionFactory.wrapException("Error building SqlSession.", e);

    } finally {

      ErrorContext.instance().reset();

      try {

        inputStream.close();

      } catch (IOException e) {

        // Intentionally ignore. Prefer previous error.

      }

    }

  }


  public SqlSessionFactory build(Configuration config) {

    return new DefaultSqlSessionFactory(config);

  }

}

从SqlSessionFactoryBuilder这个类的源码中可以看出,它有9个build方法的重载。

根本的有三个重载的build方法:

1、  public SqlSessionFactory build(Reader reader, String environment, Properties properties)

2、  public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties)

3、  public SqlSessionFactory build(Configuration config)



结合Mybatis的基础配置文件结构,整个SqlSessionFactory的创建过程就非常明了了。<Configuration>与Configuration配置类对应,它涵盖了创建SqlSessionFactory所需要的全部配置信息。

整个流程如下:

baseConfigXmlFile-------------->XmlConfigBuilder解析---------->Configuration类对象----------->SqlSessionFactoryBuilder--------------->SqlSessionFactory对象。

接下来细说下面这个方法:

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties)

enviroment是指定默认的数据库环境如下所示

<environments default="development">

      <environment id="development">

        <transactionManager type="JDBC" />

        <dataSource type="POOLED">

          <property name="driver" value="com.mysql.jdbc.Driver" />

          <property name="driver.encoding" value="utf8" />

          <property name="url" value="jdbc:mysql://localhost/book"/>

          <property name="username" value="root" />

          <property name="password" value="123456" />

        </dataSource>

      </environment>

    </environments>

当这个参数不为null时,将覆盖基础配置文件中的值,可以在一个基础配置文件中配置多个数据库环境,然后在创建不同数据库的SqlSessionFactory比如存在数据库环境配置db1、db2

<environments default="development">

      <environment id="db1">

......

      </environment>

<environment id="db2">

......

      </environment>

    </environments>

String baseConfigFilePath = "mybatis-config.xml";

InputStream is1 = Resources.getResourceAsStream(baseConfigFilePath);

InputSream is2 = Resources.getResourceAsStream(baseConfigFilePath);

SqlSessionFactory db1SqlSessionFactory = new SqlSessionFactoryBuilder().build(is1, "db1");

SqlSessionFactory db1SqlSessionFactory = new SqlSessionFactoryBuilder().build(is2, "db2");

注意这里:虽然配置文件是同一个,但是不能共享同一个InputSream对象,因为SqlSessionFactoryBuilder在创建完SqlSessionFactory对象后会关闭InputStream对象。


再看properties这个参数,可以通过properties参数配置属性信息,同样它将覆盖基础配置文件中的相同属性名称的属性的值。

String resource = "mybatis-config.xml"//基础配置文件

InputStream inputStream;

InputSream is = Resource.getResourceAsStream("jdbc.properties");

Properties props = new Properties();

props.load(is);

String userName = props.getProperty("database.username");

String password = props.getProperty("database.password");

//解密用户名和密码

props.put("database.username", CodeUtils.decode(userName));

props.put("database.password", CodeUtils.decode(password));

inputStream = Resource.getResourceAsStream(resource);

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream, props);

三种配置方式优先级:代码方式>properties文件方式>property子元素方式


当SqlSessionFactory对象创建完成后,我们如果需要修改配置信息怎么办呢?

SqlSessionFactory对象保存了创建它的Configuration对象的信息,我们可以通过

SqlSessionFactory对象的getConfiguration()方法获取Configuration配置对象。

而Confiration配置对象中,保存了各种注册器的引用(别名注册器、类型转换器等)


可以通过这些方法动态地改变配置信息。如我们可以获取别名注册器在代码中动态地注册别名:

Configuration configuration = factory.getConfiguration();

TypeAliasRegistry typeAliasRegistry = configuration.getTypeAliasRegistry();

typeAliasRegistry.registerAlias("key", "value");

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,734评论 0 4
  • ORM框架Mybatis几个重要的流程: SqlSessionFactoryBuilder,用来创建SqlSess...
    小雪的笔记阅读 435评论 0 1
  • MyBatis 理论篇 [TOC] 什么是MyBatis  MyBatis是支持普通SQL查询,存储过程和高级映射...
    有_味阅读 2,977评论 0 26
  • MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架,其主要就完成2件事情: 封装JDBC...
    慕容小伟阅读 1,091评论 0 2
  • lambda表达式(又被成为“闭包”或“匿名方法”)方法引用和构造方法引用扩展的目标类型和类型推导接口中的默认方法...
    183207efd207阅读 1,502评论 0 5