获取SqlSessionFactory
1、首先读取XML配置文件
InputStream inputStream = Resources.getResourceAsStream(DEFAULT_MYBATIS_CONFIG_FILE);
2、实例化SqlSessionFactory(主要是读取配置文件流并将这些配置信息存放在Configuration类中)
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
3、SqlSessionFactoryBuilder的build方法如下
//创建一个配置文件流的解析对象XMLConfigBuilder,将环境和配置文件流赋予解析类
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
//1.解析类对配置文件进行解析并将解析的内容存放到Configuration对象
//2.build返回SqlSessionFactory
return build(parser.parse());
4、实例化XMLConfigBuilder
public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {
this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);
}
//实际调用构造函数如下
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;
}
其中,new Configuration()。将默认的配置注册进Configuration对象。
5、解析配置文件的内容主要在XMLConfigBuilder的parse方法。
public Configuration parse() {
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
private void parseConfiguration(XNode root) {
try {
propertiesElement(root.evalNode("properties")); //issue #117 read properties first
typeAliasesElement(root.evalNode("typeAliases"));
pluginElement(root.evalNode("plugins"));
objectFactoryElement(root.evalNode("objectFactory"));
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
settingsElement(root.evalNode("settings"));
environmentsElement(root.evalNode("environments")); // read it after objectFactory and objectWrapperFactory issue #631
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);
}
}
将配置文件信息加载值内存信息中。
6、最后的build方法是通过Configuration配置对象创建出DefaultSqlSessionFactory实例。DefaultSqlSessionFactory是SqlSessionFactory的默认实现
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
7、这里使用了到“建造者设计模式”。
SqlSessionFactoryBuilder扮演具体的建造者
Configuration类负责建造的细节工作
SqlSessionFactory的实现类是建造出来的产品。
得到SqlSession实例
1、通过接口得到SqlSession实例
SqlSession sqlSession = MyBatisUtil.getSqlSessionFactory().openSession();
2、我们来看下openSession()具体做了哪些事情
public SqlSession openSession() {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
ExcutorType:执行类型。有SIMPLE、REUSE、BATCH,默认是SIMPLE
实际调用的openSessionFromDataSource方法如下
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
//获取环境信息,包括连接数据的参数信息及事务等
final Environment environment = configuration.getEnvironment();
//获取事务
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
//从事务工厂中获得一个执行器实例
final Executor executor = configuration.newExecutor(tx, execType, autoCommit);
//返回SqlSession的默认实例
return new DefaultSqlSession(configuration, executor);
} catch (Exception e) {
closeTransaction(tx); // may have fetched a connection so lets call close()
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
该系列文章参考如下书籍及文章:
《Java Persistence with MyBatis 》
《http://www.cnblogs.com/hzhuxin/p/3349836.html》
《http://www.iteye.com/topic/1112327》
《http://www.iteye.com/blogs/subjects/mybatis_internals》
《http://denger.me/2011/05/mybatis-and-spring-interface-integrated/》