Mybatis如何加载配置文件 源码解读parameterType


 

我能学到什么

--------------------------------------------------------------------------------------------------------------------------------------------------

1.        Mybatis加载解析配置文件流程

2.        如何解析配置文件里面的parameterType

3.        提高看源码的能力

4.        查看源码编写方式,明白应该如何规范的写出解析XML文件的代码,提高编码能力

5.        学会使用框架上解决问题的思维和常用手段

    • l        利用配置文件解耦
    • l        利用反射、动态代理、泛型、设计模式等解决框架级别的问题。
    • l        框架的设计思想

 ----------------------------------------------------------------------------------------------------------------------------------------------------


题外问题

如下一段代码:调用了Mybatis提供的加载及解析配置文件功能。

public class DBAccess {
    public SqlSession getSqlSession() throws IOException
    {
        //1、通过配置文件获取数据库连接相关信息
        Readerreader=Resources.getResourceAsReader("hdu/terence/config/Configuration.xml");
        //2、通过配置信息构建SqlSessionFactory
        SqlSessionFactorySSF=new SqlSessionFactoryBuilder().build(reader);
        //3、通过SqlSessionFactory打开数据库会话
        SqlSessionsqlSession=SSF.openSession();
        return sqlSession;
    }
}

题外话

上述代码在Mybatis中的使用存在两个问题:

问题一:每次访问数据调用Sql语句的时候,都会临时的去调用加载配置文件解析,很耗性能。

问题二:另外,每次访问,都需要反复加载,耗费时间。

这个问题的暂且说一下解决办法:

针对第一个配置文件加载的时机问题,要自己写一个监听器,容器在启动的时候加载配置文件。

 【加载时机】-->【监听器】

针对第二个问题,通过单利模式存放监听器加载的配置内容,防止其重复加载。

 【重复加载】-->【单例模式】

在实际开发中则是通过Spring+Mybatis解决上述两个问题的。

 

 

源码解读

加载上篇

先说一下上述加载解析配置文件的代码:根据注释可知,此部分分为三步。

1.     通过配置文件获取数据库连接相关信息

2.     通过配置信息构建SqlSessionFactory

3.        通过SqlSessionFactory打开数据库会话

其中,在第二步通过build()方法进入Mybatis当中。

上述build()方法是在SqlSessionFactoryBuilder.class这个类中实现的:

public SqlSessionFactorybuild(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 previouserror.
      }
    }
  } 

看此句:

XMLConfigBuilderparser = new XMLConfigBuilder(reader, environment, properties)表示将转换后的reader、配置环境以及配置的各个属性包装在parser解析项中,然后通过return build(parser.parse())返回一个会话工厂,仍然需要进入另外的源码XMLConfigBilder.class中,找到parser()解析方法:

  private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
    super(new Configuration());
    ErrorContext.instance().resource("SQL Mapper Configuration");
    this.configuration.setVariables(props);
    this.parsed = false;
    this.environment = environment;
    this.parser = parser;
  } 
  public Configuration parse() {
    if (parsed) {
      throw new BuilderException("Each XMLConfigBuilder can only beused once.");
    }
    parsed = true;
    parseConfiguration(parser.evalNode("/configuration"));
    return configuration;
  }

     在构造函数当中,将parsed=flase,在configuration parse()方法中,先判别parsed是否为ture,如果是True,则表示已经加载解析过,抛出异常(防止重复加载,耗费性能耗费时间,防止出现类似于调用sql语句时候每次都调用DBAccesss一样出现的两个问题),否则将其赋值为true,然后继续解析加载文件,通过parser.evalNode("/configuration")进入XPathParser.Class中,通过里面的Document文件读取对象来解析文件(那么由此可以说明,Mybatis解析xml文件使用的是Dom对象和Java JDK中的类进行的)。

XPathParser.Class文件相关内容:

构造函数:

public XPathParser(String xml) {
    commonConstructor(false, null, null);
    this.document = createDocument(new InputSource(new StringReader(xml)));
  }
public XPathParser(Reader reader) {
    commonConstructor(false, null, null);
    this.document = createDocument(new InputSource(reader));
  }

看第二个构造函数可知此步表示reader对象的转化为输入流,然后转化为document对象。

 

配置文件

上述的源码目的是为了进入配置文件Configuration.xml文件解析,下面先贴出来配置文件

贴总配置文件Configuration.xml:





 
     
      
     

 
  
         
      
        
           
      
        
        
             
        
        
           
    
  
 

  
    
    
    
   
 

子配置文件Dao.xml---- Message.xml



 

 
   
     
     
    
    
    
  
 
   

 

梳理总流程

OK,退出来梳理总流程:

    首先,建立一个总配置文件的解析流,使用Document对象代替reader对象,成为了新的配置文件解析代言人,然后Document对象进入Configuration.xml配置文件,解析出……的配置项,找到Dao.xml配置文件的路径,根据该路径,进入该配置文件(Message.xml)。

   最后,进入Dao.xml配置文件之后,使用JDK中的Dom对象逐个解析,肯定能找到节点—>获取该节点的parameterType属性—>根据该属性值利用反射获取对应类名。

 

OK,完毕!

你可能感兴趣的:(【Mybatis】)