本文对mybatis的配置不做讲解,只从源码层面来分析mybatis的加载过程。
我们在使用mybatis时,一般流程如下,实例化一个sqlSessionFactory,然后通过sqlSessionFactory来获取一个sqlSession。
InputStream inputStream=null; try{ inputStream= Resources.getResourceAsStream("mybatis-config.xml"); //配置文件 sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession=sqlSessionFactory.openSession()
}catch(Exception e){ e.printStackTrace(); }
先看下sqlSessionFactory的build过程,首先将mybatis-config.xml作为一个输入流传入给build()方法,build的代码如下:
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { SqlSessionFactory var5; try { XMLConfigBuilder e = new XMLConfigBuilder(inputStream, environment, properties); //将配置文件加载为XMLConfig var5 = this.build(e.parse()); //构建SqlSessionFactory } catch (Exception var14) { throw ExceptionFactory.wrapException("Error building SqlSession.", var14); } finally { ErrorContext.instance().reset(); try { inputStream.close(); } catch (IOException var13) { ; } } return var5; }
//XMConfigBuilder中使用的XPathParser,XPathParser中使用的createDocument方法来将DOM加载到XPathParser中 private Document createDocument(InputSource inputSource) { try { DocumentBuilderFactory e = DocumentBuilderFactory.newInstance(); e.setValidating(this.validation); e.setNamespaceAware(false); e.setIgnoringComments(true); e.setIgnoringElementContentWhitespace(false); e.setCoalescing(false); e.setExpandEntityReferences(true); DocumentBuilder builder = e.newDocumentBuilder(); builder.setEntityResolver(this.entityResolver); builder.setErrorHandler(new ErrorHandler() { public void error(SAXParseException exception) throws SAXException { throw exception; } public void fatalError(SAXParseException exception) throws SAXException { throw exception; } public void warning(SAXParseException exception) throws SAXException { } }); return builder.parse(inputSource);//将inputSource加载成Document,最后存储到XpathParser中 } catch (Exception var4) { throw new BuilderException("Error creating document instance. Cause: " + var4, var4); } }
再从最开始的var5 = this.build(e.parse())看,先看一下e.parse()方法:
public Configuration parse() { if(this.parsed) { throw new BuilderException("Each XMLConfigBuilder can only be used once."); } else { this.parsed = true; this.parseConfiguration(this.parser.evalNode("/configuration"));//解析configuration标签下的内容到Configuration对象中 return this.configuration; } } private void parseConfiguration(XNode root) { //分别解析各个标签下内容到Configuration对象中 try { this.propertiesElement(root.evalNode("properties")); //properties标签 Properties e = this.settingsAsProperties(root.evalNode("settings"));//settings标签 this.loadCustomVfs(e); 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(e); this.environmentsElement(root.evalNode("environments"));//environments标签 /this.databaseIdProviderElement(root.evalNode("databaseIdProvider")); this.typeHandlerElement(root.evalNode("typeHandlers")); this.mapperElement(root.evalNode("mappers")); //Mappers对象 } catch (Exception var3) { throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + var3, var3); } }
这里解析mybatis-config.xml中的所有标签出来,并加载到Configuration对象中,mybatis-config.xml的文件如下:
<configuration>
<properties resource="jdbc.properties"/> <!-- 属性文件,也可以直接在本文件中写properties属性 -->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<typeAliases>
<package name="com.mymvc.bean"></package>
<package name="com.java1234.model"></package>
</typeAliases>
<environments default="development"> <!-- 默认开发环境 -->
<environment > <!-- 开发环境 -->
<transactionManager type="JDBC" /> <!-- 事务管理器,JDBC和MANAGED(tomcat不支持) -->
<dataSource type="POOLED"> <!-- 有UNPOOLED,POOLED,JNDI三种 -->
<property name="driver" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
<environment > <!-- 测试环境 -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<mappers>
<package name="com.java1234.mappers" />
</mappers>
</configuration>