0
点赞
收藏
分享

微信扫一扫

深入理解mybatis原理(一) Mybatis初始化机制详解


 对于任何框架而言,在使用前都要进行一系列的初始化,MyBatis也不例外。本章将通过以下几点详细介绍MyBatis的初始化过程。

    1.MyBatis的初始化做了什么

    2. MyBatis基于XML配置文件创建Configuration对象的过程

    3. 手动加载XML配置文件创建Configuration对象完成初始化,创建并使用SqlSessionFactory对象

    4. 涉及到的设计模式

一、 MyBatis的初始化做了什么

    任何框架的初始化,无非是加载自己运行时所需要的配置信息。MyBatis的配置信息,大概包含以下信息,其高层级结构如下:

× configuration 配置

    × properties 属性
    × settings 设置
   ×typeAliases 类型命名
   ×typeHandlers 类型处理器
   ×objectFactory 对象工厂
   ×plugins 插件
   ×environments 环境
      ×environment 环境变量
      ×transactionManager 事务管理器
      ×dataSource 数据源
×映射器


MyBatis的上述配置信息会配置在XML配置文件中,那么,这些信息被加载进入MyBatis内部,MyBatis是怎样维护的呢?

MyBatis采用了一个非常直白和简单的方式---使用org.apache.ibatis.session.Configuration

深入理解mybatis原理(一) Mybatis初始化机制详解_配置文件


MyBatis根据初始化好Configuration信息,这时候用户就可以使用MyBatis进行​​数据库​​操作了。

可以这么说,MyBatis初始化的过程,就是创建 Configuration对象的过程。

MyBatis的初始化可以有两种方式:

  • 基于XML配置文件:基于XML配置文件的方式是将MyBatis的所有配置信息放在XML文件中,MyBatis通过加载并XML配置文件,将配置文信息组装成内部的Configuration对象
  • 基于Java API:这种方式不使用XML配置文件,需要MyBatis使用者在Java代码中,手动创建Configuration对象,然后将配置参数set 进入Configuration对象中

(PS:  MyBatis具体配置信息有哪些,又分别表示什么意思,不在本文的叙述范围,读者可以参考我的​​《Java Persistence withMyBatis 3 (中文版)》 的第二章 引导MyBatis​​中有详细的描述)

接下来我们将通过 基于XML配置文件方式的MyBatis初始化,深入探讨MyBatis是如何通过配置文件构建Configuration对象,并使用它的。

    

二、MyBatis基于XML配置文件创建Configuration对象的过程

现在就从使用MyBatis的简单例子入手,深入分析一下MyBatis是怎样完成初始化的,都初始化了什么。看以下代码:



[java] ​​view plain​​ ​​copy​​




  1. String resource = "mybatis-config.xml";  
  2. InputStream inputStream = Resources.getResourceAsStream(resource);  
  3. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  
  4. SqlSession sqlSession = sqlSessionFactory.openSession();  
  5. List list = sqlSession.selectList("com.foo.bean.BlogMapper.queryAllBlogInfo");  




[java]  ​​view plain​​  ​​copy​​



  1. String resource = "mybatis-config.xml";  
  2. InputStream inputStream = Resources.getResourceAsStream(resource);  
  3. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  
  4. SqlSession sqlSession = sqlSessionFactory.openSession();  
  5. List list = sqlSession.selectList("com.foo.bean.BlogMapper.queryAllBlogInfo");  


有过MyBatis使用经验的读者会知道,上述语句的作用是执行com.foo.bean.BlogMapper.queryAllBlogInfo 定义的SQL语句,返回一个List结果集。总的来说,上述代码经历了mybatis初始化 -->创建SqlSession -->执行SQL语句 返回结果三个过程。

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  现在就让我们看看第三句到底发生了什么。

MyBatis初始化基本过程:

SqlSessionFactoryBuilder根据传入的数据流生成Configuration对象,然后根据Configuration对象创建默认的SqlSessionFactory实例。


初始化的基本过程如下序列图所示:


三、手动加载XML配置文件创建Configuration对象完成初始化,创建并使用SqlSessionFactory对象

我们可以使用XMLConfigBuilder手动解析XML配置文件来创建Configuration对象,代码如下:



[java] ​​view plain​​ ​​copy​​




  1. String resource = "mybatis-config.xml";  
  2. InputStream inputStream = Resources.getResourceAsStream(resource);  
  3. //手动创建XMLConfigBuilder,并解析创建Configuration对象  
  4. XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, null,null);  
  5. Configuration configuration=parse();  
  6. //使用Configuration对象创建SqlSessionFactory  
  7. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);  
  8. //使用MyBatis  
  9. SqlSession sqlSession = sqlSessionFactory.openSession();  
  10. List list = sqlSession.selectList("com.foo.bean.BlogMapper.queryAllBlogInfo");  




[java]  ​​view plain​​  ​​copy​​



  1. String resource = "mybatis-config.xml";  
  2. InputStream inputStream = Resources.getResourceAsStream(resource);  
  3. //手动创建XMLConfigBuilder,并解析创建Configuration对象  
  4. XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, null,null);  
  5. Configuration configuration=parse();  
  6. //使用Configuration对象创建SqlSessionFactory  
  7. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);  
  8. //使用MyBatis  
  9. SqlSession sqlSession = sqlSessionFactory.openSession();  
  10. List list = sqlSession.selectList("com.foo.bean.BlogMapper.queryAllBlogInfo");  


四、涉及到的设计模式

初始化的过程涉及到创建各种对象,所以会使用一些创建型的设计模式。在初始化的过程中,Builder模式运用的比较多。

Builder模式应用1: SqlSessionFactory的创建

 对于创建SqlSessionFactory时,会根据情况提供不同的参数,其参数组合可以有以下几种:

深入理解mybatis原理(一) Mybatis初始化机制详解_mybatis_06

由于构造时参数不定,可以为其创建一个构造器Builder,将SqlSessionFactory的构建过程和表示分开:

深入理解mybatis原理(一) Mybatis初始化机制详解_Source_07

MyBatis将SqlSessionFactoryBuilder和SqlSessionFactory相互独立。

Builder模式应用2: 数据库连接环境Environment对象的创建

在构建Configuration对象的过程中,XMLConfigParser解析 mybatis XML配置文件节点<environment>节点时,会有以下相应的代码:



[java] ​​view plain​​ ​​copy​​




  1. private void environmentsElement(XNode context) throws Exception {  
  2. if (context != null) {  
  3. if (environment == null) {  
  4. "default");  
  5.     }  
  6. for (XNode child : context.getChildren()) {  
  7. "id");  
  8. //是和默认的环境相同时,解析之  
  9. if (isSpecifiedEnvironment(id)) {  
  10. "transactionManager"));  
  11. "dataSource"));  
  12.         DataSource dataSource = dsFactory.getDataSource();  
  13.   
  14. //使用了Environment内置的构造器Builder,传递id 事务工厂和数据源  
  15. new Environment.Builder(id)  
  16.             .transactionFactory(txFactory)  
  17.             .dataSource(dataSource);  
  18.         configuration.setEnvironment(environmentBuilder.build());  
  19.       }  
  20.     }  
  21.   }  
  22. }  




[java]  ​​view plain​​  ​​copy​​



  1. private void environmentsElement(XNode context) throws Exception {  
  2. if (context != null) {  
  3. if (environment == null) {  
  4. "default");  
  5.     }  
  6. for (XNode child : context.getChildren()) {  
  7. "id");  
  8. //是和默认的环境相同时,解析之  
  9. if (isSpecifiedEnvironment(id)) {  
  10. "transactionManager"));  
  11. "dataSource"));  
  12.         DataSource dataSource = dsFactory.getDataSource();  
  13.   
  14. //使用了Environment内置的构造器Builder,传递id 事务工厂和数据源  
  15. new Environment.Builder(id)  
  16.             .transactionFactory(txFactory)  
  17.             .dataSource(dataSource);  
  18.         configuration.setEnvironment(environmentBuilder.build());  
  19.       }  
  20.     }  
  21.   }  
  22. }  



在Environment内部,定义了静态内部Builder类:



[java] ​​view plain​​ ​​copy​​




  1. public final class Environment {  
  2. private final String id;  
  3. private final TransactionFactory transactionFactory;  
  4. private final DataSource dataSource;  
  5.   
  6. public Environment(String id, TransactionFactory transactionFactory, DataSource dataSource) {  
  7. if (id == null) {  
  8. throw new IllegalArgumentException("Parameter 'id' must not be null");  
  9.     }  
  10. if (transactionFactory == null) {  
  11. throw new IllegalArgumentException("Parameter 'transactionFactory' must not be null");  
  12.     }  
  13. this.id = id;  
  14. if (dataSource == null) {  
  15. throw new IllegalArgumentException("Parameter 'dataSource' must not be null");  
  16.     }  
  17. this.transactionFactory = transactionFactory;  
  18. this.dataSource = dataSource;  
  19.   }  
  20.   
  21. public static class Builder {  
  22. private String id;  
  23. private TransactionFactory transactionFactory;  
  24. private DataSource dataSource;  
  25.   
  26. public Builder(String id) {  
  27. this.id = id;  
  28.     }  
  29.   
  30. public Builder transactionFactory(TransactionFactory transactionFactory) {  
  31. this.transactionFactory = transactionFactory;  
  32. return this;  
  33.     }  
  34.   
  35. public Builder dataSource(DataSource dataSource) {  
  36. this.dataSource = dataSource;  
  37. return this;  
  38.     }  
  39.   
  40. public String id() {  
  41. return this.id;  
  42.     }  
  43.   
  44. public Environment build() {  
  45. return new Environment(this.id, this.transactionFactory, this.dataSource);  
  46.     }  
  47.   
  48.   }  
  49.   
  50. public String getId() {  
  51. return this.id;  
  52.   }  
  53.   
  54. public TransactionFactory getTransactionFactory() {  
  55. return this.transactionFactory;  
  56.   }  
  57.   
  58. public DataSource getDataSource() {  
  59. return this.dataSource;  
  60.   }  
  61.   
  62. }  




[java]  ​​view plain​​  ​​copy​​



  1. public final class Environment {  
  2. private final String id;  
  3. private final TransactionFactory transactionFactory;  
  4. private final DataSource dataSource;  
  5.   
  6. public Environment(String id, TransactionFactory transactionFactory, DataSource dataSource) {  
  7. if (id == null) {  
  8. throw new IllegalArgumentException("Parameter 'id' must not be null");  
  9.     }  
  10. if (transactionFactory == null) {  
  11. throw new IllegalArgumentException("Parameter 'transactionFactory' must not be null");  
  12.     }  
  13. this.id = id;  
  14. if (dataSource == null) {  
  15. throw new IllegalArgumentException("Parameter 'dataSource' must not be null");  
  16.     }  
  17. this.transactionFactory = transactionFactory;  
  18. this.dataSource = dataSource;  
  19.   }  
  20.   
  21. public static class Builder {  
  22. private String id;  
  23. private TransactionFactory transactionFactory;  
  24. private DataSource dataSource;  
  25.   
  26. public Builder(String id) {  
  27. this.id = id;  
  28.     }  
  29.   
  30. public Builder transactionFactory(TransactionFactory transactionFactory) {  
  31. this.transactionFactory = transactionFactory;  
  32. return this;  
  33.     }  
  34.   
  35. public Builder dataSource(DataSource dataSource) {  
  36. this.dataSource = dataSource;  
  37. return this;  
  38.     }  
  39.   
  40. public String id() {  
  41. return this.id;  
  42.     }  
  43.   
  44. public Environment build() {  
  45. return new Environment(this.id, this.transactionFactory, this.dataSource);  
  46.     }  
  47.   
  48.   }  
  49.   
  50. public String getId() {  
  51. return this.id;  
  52.   }  
  53.   
  54. public TransactionFactory getTransactionFactory() {  
  55. return this.transactionFactory;  
  56.   }  
  57.   
  58. public DataSource getDataSource() {  
  59. return this.dataSource;  
  60.   }  
  61.   
  62. }  



举报

相关推荐

0 条评论