本文主要分析SqlSessionFactory的构建过程

SqlSessionFactoryBuilder从XML中构建SqlSessionFactory

String resource = "org/mybatis/example/mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

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

SqlSessionFactoryBuilder用来创建SqlSessionFactory实例,一旦创建了SqlSessionFactory,就不再需要它了

public SqlSessionFactory build(InputStream inputStream) { return build(inputStream, null, null);}

调用

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties)

源码如下:

/** * 根据配置创建SqlSessionFactory * * @param inputStream 配置文件输入流 * @param environment 环境名称 * @param properties 外部配置 * @return */ public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { try { XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties); //parser.parse()读取配置文件返回configuration //build()根据返回的configuration创建SqlSessionFactory 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. } } }

最终创建DefaultSqlSessionFactory实例

public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config);}

其中

XMLConfigBuilder与Configuration

XMLConfigBuilder的方法parse()

public Configuration parse() { if (parsed) { throw new BuilderException("Each XMLConfigBuilder can only be used once."); } parsed = true; //读取mybatis-config.xml配置信息,"configuration"是根结点 parseConfiguration(parser.evalNode("/configuration")); return configuration;}

XMLConfigBuilder的方法parseConfiguration(XNode root)

/** * 读取配置文件组装configuration * @param root 配置文件的configuration节点 */private void parseConfiguration(XNode root) { try { //issue #117 read properties first propertiesElement(root.evalNode("properties")); typeAliasesElement(root.evalNode("typeAliases")); pluginElement(root.evalNode("plugins")); objectFactoryElement(root.evalNode("objectFactory")); objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); reflectionFactoryElement(root.evalNode("reflectionFactory")); settingsElement(root.evalNode("settings")); // read it after objectFactory and objectWrapperFactory issue #631 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); }}

关于配置文件相关的源码分析参看:

http://www.iocoder.cn/MyBatis/udbwcso/Configuration

设计模式

从SqlSessionFactory和Configuration的创建过程中可以看出它们都使用了建造者模式.