mybatis的认识(一)

目录

  • MyBatis的初始化做了什么
  • MyBatis的创建过程
  • 手动加载
  • 设计的几个主要设计模式

背景

简单啰嗦一下背景

  • MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
  • iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)
  • 自己绘制的图将就着看,重要的是意思O(∩_∩)O哈哈~
    在这里插入图片描述

初始化做了什么

在这里插入图片描述

  • MyBatis基于XML配置文件创建Configuration对象的过程 手动加载XML配置文件创建Configuration对象完成初始化,创建并使用SqlSessionFactory对象 ,其实这里已经涉及到设计模式了,最后会讲。
  • 对于任何框架而言,在使用前都要进行一系列的初始化,就是使用对象要初始化一样。框架的初始化,无非是加载自己运行时所需要的配置信息。

详细配置

在这里插入图片描述

-properties 属性
-settings 设置

  • typeAliases 类型命名
  • typeHandlers 类型处理器
  • bjectFactory 对象工厂
  • plugins 插件
  • environments 环境
  • environment 环境变量
  • transactionManager 事务管理器
  • dataSource 数据源

映射器

在这里插入图片描述

  • MyBatis配置信息会配置在XML配置文件中,这些信息被加载进入MyBatis内部。使用 org.apache.ibatis.session.Configuration 对象作为一个所有配置信息的容器,why?
  • 因为Configuration对象的组织结构和XML配置文件的组织结构几乎完全一样。
  • 然后MyBatis根据初始化好Configuration信息,这时候用户就可以使用MyBatis进行数据库操作了
**到这里大家可能都知道了,其实MyBatis初始化的过程,就是创建 Configuration对象的过程。 ** 

那么初始化的方式都有哪些:

在这里插入图片描述

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

使用MyBatis的简单例子分析MyBatis是怎样完成初始化和初始化内容:

在这里插入图片描述


		String resource = "mybatis的mapper文件名字.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //第一个是语句,第二个是对应的实体类
        sqlSession.selectList("select * from analysis_Report",AnalysisReport.class);
        
配着对应的流程图

在这里插入图片描述

重点:
  • SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  • 为什么?Because那个configuration的创建过程就在里面
  • 初始化基本过程: SqlSessionFactoryBuilder根据传入的数据流生成Configuration 对象,然后根据Configuration对象创建默认的SqlSessionFactory实例。
  • 看一下源码,经过抽取的部分源码,并加上响应注释方便理解
public SqlSessionFactory build(InputStream inputStream) {
    return build(inputStream, null, null);
  }

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
    try {
	  //1.创建XMLConfigBuilder对象用来解析XML配置文件,生成Configuration对象
      XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
	  //2.讲XML配置文件的信息解析成Java对象Configuration对象
	  Configuration config = parser.parse();
	  //3.根据Configuration对象创建出SqlSessionFactory对象
      return build(config);
    } 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 Configuration parse() {
    if (parsed) {
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
  }
 
 //从此可以看出,mybatis内部通过Configuration对象来创建SqlSessionFactory,
 //程序员们可以自己通过API构造好Configuration对象或者再加一些别的自定义的东西都可以
 //然后调用此方法创建SqlSessionFactory
 public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }

创建Configuration对象的过程在哪里?
  • 在parse()方法里! XMLConfigBuilder会将XML配置文件的信息转换 为Document对象,而XML配置定义文件DTD转换成XMLMapperEntityResolver对 象,然后将二者封装到XpathParser对象中,XpathParser的作用是提供根据Xpath表 达式获取基本的DOM节点Node信息的操作。
  • 解析node节点信息:
    • 解析此Node节点的子Node:(configuration配置的东西) properties, settings, typeAliases,typeHandlers, objectFactory, objectWrapperFactory, plugins, environments,databaseIdProvider, mappers
      在这里插入图片描述
public Configuration parse() {
    if (parsed) {
      throw new BuilderException("Each XMLConfigBuilder can only be used once.");
    }
    parsed = true;
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
  }
//解析 "/configuration"节点下的子节点信息,然后将解析结果设置到configuration对象中 
  private void parseConfiguration(XNode root) {
    try {
	  //1.首先处理properties节点		
      Properties settings = settingsAsPropertiess(root.evalNode("settings"));
      propertiesElement(root.evalNode("properties"));
      loadCustomVfs(settings);
	  //2.处理typeAliases
      typeAliasesElement(root.evalNode("typeAliases"));
      pluginElement(root.evalNode("plugins"));
	  //3.处理objectFactory
      objectFactoryElement(root.evalNode("objectFactory"));
      objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
      reflectorFactoryElement(root.evalNode("reflectorFactory"));
	   //4.处理settings
      settingsElement(settings);
      // 5.处理environments的节点
      environmentsElement(root.evalNode("environments"));
      databaseIdProviderElement(root.evalNode("databaseIdProvider"));
      typeHandlerElement(root.evalNode("typeHandlers"));
      mapperElement(root.evalNode("mappers"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
    }
  }

如何将解析出来的值设置到configuration中??
举个栗子,将environments的信息解析出来,设置到Configuration对象 ,Look!!!

private void environmentsElement(XNode context) throws Exception {
    if (context != null) {
      if (environment == null) {
        environment = context.getStringAttribute("default");
      }
      for (XNode child : context.getChildren()) {
        String id = child.getStringAttribute("id");
        if (isSpecifiedEnvironment(id)) {
			
		  //1.创建事物工厂 TransactionFactory
          TransactionFactory txFactory = transactionManagerElement(child.evalNode("transactionManager"));
          DataSourceFactory dsFactory = dataSourceElement(child.evalNode("dataSource"));
		  //2.创建数据源DataSource
          DataSource dataSource = dsFactory.getDataSource();
		  //3.构造Environment对象 - 下面是一个在Environment内部,
		  //定义了静态内部Builder类最后的涉及模式会提到,不懂的朋友可以去查一下
          Environment.Builder environmentBuilder = new Environment.Builder(id)
              .transactionFactory(txFactory)
              .dataSource(dataSource);
		  //4.将创建的Environment对象设置到configuration 对象中
          configuration.setEnvironment(environmentBuilder.build());
        }
      }
    }
  }
private boolean isSpecifiedEnvironment(String id) {
    if (environment == null) {
      throw new BuilderException("No environment specified.");
    } else if (id == null) {
      throw new BuilderException("Environment requires an id attribute.");
    } else if (environment.equals(id)) {
      return true;
    }
    return false;
  }

  • 将这些值解析出来设置到Configuration对象中,最后返回configuration对象。
  • 流程图可以参考以下面的:

在这里插入图片描述![在这里插入图片描述](https://img-blog.csdnimg.cn/20190309182945910.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2hlX211X3JlbnNoZW4=,size_16,color_FFFFFF,t_70

注意:解析XML配置文件子节点<mappers>的方法mapperElements(root.evalNode("mappers")), 它将解析我们配置的Mapper.xml配置文件,Mapper配置文件可以说是MyBatis的核心,MyBatis的特性和理念都体现在此Mapper的配置和设计上 解析environments节点,并将结果设置到Configuration对象中

手动加载XML配置文件

这个再上面的代码示例中展示过了,只不过,在手动加载过程会有一些其他自定义的代码

上面代码中涉及到的涉及模式:

SqlSessionFactoryBuilder:
  • SqlSessionFactory的构造器,用于创建SqlSessionFactory,采用了Builder设计模式 Configuration
SqlSessionFactory:
  • SqlSession工厂类,以工厂形式创建SqlSession对象,采用了Factory工厂设计模式 XmlConfigParser
XmlConfigParser :
  • 负责将mybatis-config.xml配置文件解析成Configuration对象,共SqlSessonFactoryBuilder使用,创建SqlSessionFactory

设计模式(主要常见)

在这里插入图片描述

建议对这些不熟悉的,多去看一下设计模式,一定要熟练

下面主要说一下Builder模式

  • 用代码说明
  • SqlSessionFactory的创建
    在这里插入图片描述在这里插入图片描述
 - 还有就是在解释mybatis如何解析那些节点然后存到configuration对象中时提到的environment节点,同样是builder

XMLConfigParser解析配置文件节点

在这里插入图片描述

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

在这里插入图片描述

总结

在这里插入图片描述

其实mybatis内部还有很多东西,今天只是分析了一下mybatis初始化的内容,希望对大家有帮助!!

下篇:mybatis的认识(二)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值