SSM-Mybatis-运行原理和解析-构建SqlSessionFactory过程

SSM-Mybatis-运行原理和解析-构建SqlSessionFactory过程

构建SqlSessionFactory过程

​ 它是听Builder模式创建的,实际可以通过SqlSessionFactoryBuilder去构建,构建分为两步:

  1. 通过org.apache.ibatis.builder.xml.XMLConfigBuilder解析配置的XML文件,将读取的内容存入到org.apache.ibatis.session.Configuration类对象中,它是一个单例模式,

  2. 使用Configuration对象去创建SqlSessionFactory,SqlSessionFactory是一个接口,因此Mybatis提供了一个默认实现类org.apache.ibatis.session.defaults.DefaultSqlSessionFactory,大部分情况下不需要创建实现类

    这是一种Builder创建方式,对于复杂的对象创建,使用构造器很难实现,使用一个类(Configuration)作为统领,一步步构建,然后通过它创建最终对象(SqlSessionFactory)

例如:在XMLConfigBuilder中一段代码:

   private void parseConfiguration(XNode root) {
    
    
        try {
    
    
            this.propertiesElement(root.evalNode("properties"));
            Properties settings = this.settingsAsProperties(root.evalNode("settings"));
            this.loadCustomVfs(settings);
            this.loadCustomLogImpl(settings);
            this.typeAliasesElement(root.evalNode("typeAliases"));
            this.pluginElement(root.evalNode("plugins"));
            this.objectFactoryElement(root.evalNode("objectFactory"));
            this.objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
            this.reflectorFactoryElement(root.evalNode("reflectorFactory"));
            this.settingsElement(settings);
            this.environmentsElement(root.evalNode("environments"));
            this.databaseIdProviderElement(root.evalNode("databaseIdProvider"));
           this.typeHandlerElement(root.evalNode("typeHandlers"));//使用这行说明
            this.mapperElement(root.evalNode("mappers"));
        } catch (Exception var3) {
    
    
            throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + var3, var3);
        }
    }

​ 上面代码是通过一步步解析XML的内容得到对应的信息,这些信息是配置文件中的内容,使用typeHandler解析方法说明,配置的typeHandler会被注册到typeHandlerRegistry对象中,该对象在XMLConfigBuilder的父类BaseBuilder

BaseBuilder部分源码分析:

public abstract class BaseBuilder {
    
    
    protected final Configuration configuration;
    protected final TypeAliasRegistry typeAliasRegistry;
    protected final TypeHandlerRegistry typeHandlerRegistry;

    public BaseBuilder(Configuration configuration) {
    
    
        this.configuration = configuration;
        this.typeAliasRegistry = this.configuration.getTypeAliasRegistry();
        this.typeHandlerRegistry = this.configuration.getTypeHandlerRegistry();//此处得知是通过Configuration获取的
    }
...
}

typeHandlerRegistry实际就是Configuration单例的一个属性,可以通过Configuration获取typeHandlerRegistry


构建Configuration

​ Configuration的作用:

  1. 读入配置文件,包括基础配置的XML和映射器XML(注解)
  2. 初始化一些基础配置,如:Mybatis别名等,一些重要的类对象(插件,映射器,Object工厂,typeHandler对象等)
  3. 提供单例:为后续创建SqlSessionFactory服务,提供配置参数
  4. 执行一些重要对象的初始化方法

构建映射器的内部组成

​ 当XMLConfigBuilder解析XML时,会将每一个SQL和其配置文件的内容保存起来,Mybatis中一条SQL和它相关配置信息由3个部分组成:

  1. MapperdStatement:保存一个映射器节点(select insert detele update)的内容,他是一个类保存了配置的信息,有一个属性很重要:sqlSoutce,通过它可以读取某条SQL配置的所有信息
  2. SqlSoutce:是提供BoundSql对象的地方,是MapperdStatement一个属性,它是一个接口,有几个重要的实现类:DynamicSqlSource,ProviderSqlSource,RawSqlSource,StaticSqlSource,作用是根据上下文和参数解析生成需要的SQL
  3. BoundSql:是一个结果对象,是SQLSoutce通过对SQL和参数的联合解析得到的SQL和参数,是建立SQL和参数的地方,有三个常用属性:sql,parameterObject,parameterMappings

在这里插入图片描述

扫描二维码关注公众号,回复: 13118628 查看本文章

​ 注意:MapperdStatement涉及的东西比较多,一般不建议修改它,容易产生错误;SqlSource是一个接口,主要作用根据参数和其他的规则组装SQL,Mybatis本身已经实现了他们,一般也不需要修改;对于最终的参数和SQL都反应在BoundSql类对象上,在插件中需要拿到他才能拿到当前运行的SQL和参数,从而对运行过程做出修改,满足特殊要求

​ BoundSql的三个重要属性:

  1. parameterObject:参数本身,可以传递简单对象,POJO或Map,注解@Param注解参数,他的一些规则:
    • 传递简单的对象,包括int double string 等,传入时候会把基本类型进行自动类型转换
    • 传递POJO或者Map,parameterObject就是传入POJO或者Map
    • 传递多个参数,如果没有@Param注解,那么Mybatis会把parameterObject变为一个Map<String,Object>对象,其键值的关系是按顺序来规划
    • 使用@Param注解,Mybatis会把parameterObject变成一个Map<String,Object>,只是把其数字的键值置换成@Param注解键值
  2. parameterMappings:是一个List,他的每一个元素都是parameterMapping对象,对象描述参数,通过它可以实现参数和SQL结合,以便Prepared Statement能通过它找他更好的parameterObject对象的属性设置参数。
  3. sql:属性就是书写在映射器里面的一条被SqlSource解析后的SQL

构建SqlSessionFactory

SqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);

​ Mybatis会根据文件流创建Configuration对象,而进构建SqlSessionFactory对象。

猜你喜欢

转载自blog.csdn.net/weixin_43958223/article/details/114440406