通过代码我们能看出myBatis建立连接用了四步
String resource = "SqlMapConfig.xml";
InputStream is = Test3.class.getClassLoader().getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = factory.openSession();
先用字符串储存核心配置文件的资源名
然后,用当前测试类的类加载器调用getResourceAsStream()方法,去找到指定资源名的绝对路径,返回一个字节输入流
SqlSessionFactoryBuilder获得这个字节流,找到核心配置文件
//通过读入配置文件,最终获得一个sqlSessionFactory
public class SqlSessionFactoryBuilder {
//这里是字符输入流的相关方法
public SqlSessionFactory build(Reader reader) {
return build(reader, null, null);
}
public SqlSessionFactory build(Reader reader, String environment) {
return build(reader, environment, null);
}
public SqlSessionFactory build(Reader reader, Properties properties) {
return build(reader, null, properties);
}
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
return build(parser.parse());//获得SqlSessionFactory
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
//以字节输入流传入配置信息,这里才是以文章开头代码的方式,调用的方法
public SqlSessionFactory build(InputStream inputStream) {
//去调用带有三个参数的build方法
return build(inputStream, null, null);
}
public SqlSessionFactory build(InputStream inputStream, String environment) {
return build(inputStream, environment, null);
}
public SqlSessionFactory build(InputStream inputStream, Properties properties) {
return build(inputStream, null, properties);
}
//调用此处的build方法
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
//解析myBatis配置文件,以字节流的方式
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
//调用下方的build方法来获得连接工厂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.
}
}
}
public SqlSessionFactory build(Configuration config) {
//获得sqlsessionFactory工厂,再从工厂中获得sqlsession
return new DefaultSqlSessionFactory(config);
}
}
连接工厂去调用openSession()方法
//调用这个openSession方法
@Override
public SqlSession openSession() {
//调用openSessionFromDataSource,从configuration中获取默认Executor对象类型,这是一个很重要的对象
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
//获得配置文件中的enviroment
final Environment environment = configuration.getEnvironment();
//从environment中获得事务
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
//获取数据源
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
//创建一个Executor对象,SqlSession的操作都是通过这个对象来实现的
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();
}
}