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配置类对应,它涵盖了创建SqlSessionFactory所需要的全部配置信息。

整个流程如下:

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

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

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

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

     

       

       

         

         

         

         

         

       

     

   

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

     

......

     

......

     

   

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");

你可能感兴趣的:(Mybatis学习总结(一)SqlSessionFactory)