MyBatis入门(二)
本文接上一编,来看看测试示例中中几行代码,究竟都干了些什么。我们采用在eclipse中设置断点的方式查看调用过程。
package org.stenio.blog.test;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.stenio.blog.model.Blog;
public class App {
/**
* @param args
*/
public static void main(String[] args) {
// MyBatis配置文件所在地址
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource); //(1)
} catch (IOException e) {
e.printStackTrace();
}
// 创建session factory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //(2)
// 利用session factory 生成 sql session
SqlSession session = sqlSessionFactory.openSession(); //(3)
try {
// 查询一条数据
Blog blog = session.selectOne("org.stenio.blog.selectBlog", "123"); //(4)
System.out.println(blog.getBlog_title());
} finally {
// 关闭session
session.close(); //(5)
}
}
}
再来回顾一下测试代码测试代码,为了方便查看,我们为关键代码标注了序号。
(1) 处代码,将mybatis-config.xml文件以输入流的形式读入内存,这里不涉及太多的技术,因为不多说。读者有兴趣可以自己去跟。
(2)处首先创建了个SqlSessionFactoryBuilder对象。我们来看下SqlSessionFactoryBuilder类。
SqlSessionFactoryBuilder类中没有任何成员属性,只有各种形式的builder方法,方法参数主要有InputStream、Reader、Properties、Configration。返回值统一为SqlSessionFactory。
示例中我们用到了build(InputStream)这个方法,下面是该方法的代码:
public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream, null, 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.
}
}
}
首先根据InputStream、environment、properties创建了一个XMLConfigBuilder对象。我们的evironment和properties是null。
然后调用了XMLConfigBuilder类的parse()方法。parse()方法的返回值是org.apache.ibatis.session.Configuration类型。
最后调用了build(Configration)方法。
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}方法中,返回了一个根据Configration新建的DefaultSqlSessionFactory对象。
再分别看Confirgration和DefaultSqlSessionFactory两个类。
Confirgration:
这里有无数属性和方法,超级多。我们没精力看下去吧。就把它理解成mybatis中的核心配置类。还是截个图吧。
再看DefaultSqlSessionFactory类:
此类中,持有一个configuration对象,各种openSession()方法、以及私有的获取和关闭transaction的方法。
这样,代码(2)处就执行完毕。
接下来看(3)处,SqlSessionFactory接口的openSession()方法。我们这里SqlSessionFactory的实例是DefaltSqlSessionFactory,所以看下DefaltSqlSessionFactory类中的openSession()方法。
public SqlSession openSession() {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
其中参数ExecutorType为SIMPLE,除此之外还有REUSE, BATCH
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);
return new DefaultSqlSession(configuration, executor, autoCommit);
} 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();
}
}上段代码主要的行为有
1.获取Environment对象
2.获取TransactionFactory
3.获取Transaction对象
4.最终获取Executor对象
5.根据configuration和executor,autoCommit生成DefaultSqlSession。
本文通过跟踪MyBatis的初始化过程,详细解析了如何加载配置文件、创建SqlSessionFactory对象,并进一步打开SqlSession进行数据库操作的具体步骤。
2664

被折叠的 条评论
为什么被折叠?



