每个mybatis应用都是以一个 SqlSessionFactory
实例为核心的,而 SqlSessionFactory
的生成其实很简单,只需要一下三行代码(基于XML配置文件实现):
String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
首先需要有XML配置文件,然后转成 InputStream
,然后使用 SqlSessionFactoryBuilder
生成 SqlSessionFactory
对象。接下来看一下具体做了什么:
首先,调用的是一个 build(InputStream inputStream)
方法:
public SqlSessionFactory build(InputStream inputStream) { return build(inputStream, null, null); }
可以看到这个方法直接调用了 build(InputStream inputStream, String environment, Properties properties)
方法,后面两个参数传的是 null
。看下具体实现:
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. } } }
忽略 try...catch...
,首先根据参数new了一个 XMLConfigBuilder
对象,可以看出这个XML解析器装载了一个实现了 EntityResolver
接口的 XMLMapperEntityResolver
对象。然后调用了下一个 build(Configuration config)
方法。看下 parser.parse()
:
public Configuration parse() { if (parsed) { throw new BuilderException("Each XMLConfigBuilder can only be used once."); } parsed = true; // 这里开始解析XML配置文件 parseConfiguration(parser.evalNode("/configuration")); return configuration; }
可以看出解析XML配置文件的代码是: parseConfiguration(parser.evalNode("/configuration"));
private void parseConfiguration(XNode root) { try { //issue #117 read properties first // 解析properties节点配置 propertiesElement(root.evalNode("properties")); // 解析settings节点配置 Properties settings = settingsAsProperties(root.evalNode("settings")); // 根据settings配置,装载自定义Vfs loadCustomVfs(settings); // 根据settings配置,装载对应的日志实现 loadCustomLogImpl(settings); // 解析别名配置 typeAliasesElement(root.evalNode("typeAliases")); // 解析插件配置 pluginElement(root.evalNode("plugins")); // 解析objectFactory配置 objectFactoryElement(root.evalNode("objectFactory")); // 解析objectWrapperFactory配置 objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); // 解析reflectorFactory配置 reflectorFactoryElement(root.evalNode("reflectorFactory")); // 把settings中的属性设置到configuration对象中去 settingsElement(settings); // 解析environment配置 // read it after objectFactory and objectWrapperFactory issue #631 environmentsElement(root.evalNode("environments")); // 解析databaseIdProvider配置, databaseIdProviderElement(root.evalNode("databaseIdProvider")); // 解析typeHandlers配置 typeHandlerElement(root.evalNode("typeHandlers")); // 解析mappers标签配置 mapperElement(root.evalNode("mappers")); } catch (Exception e) { throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e); } }
至此,mybatis配置文件解析完毕,调用 build(Configuration config)
方法生成 SqlSessionFactory
对象:
public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); }
可以看出,返回的是 DefaultSqlSessionFactory
对象.