public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//SqlSessionFactory初始化
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
//获取SqlSession
SqlSession session = factory.openSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.getUserById("1");
System.out.println(user);
}
//class:SqlSessionFactoryBuilder
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
//创建XML解析器来解析xml配置文件
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
//parser.parse()解析xml文件
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.
}
}
}
//返回包含了Configuration的DefaultSqlSession对象。
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
//把配置文件的信息解析并保存在Configuration对象中
public Configuration parse() {
//如果已经解析过了,抛出异常
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
//配置文件的根节点是configuration
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
解析配置文件:
分步骤解析xml文件的各个节点
private void parseConfiguration(XNode root) {
try {
Properties settings = settingsAsPropertiess(root.evalNode("settings"));
//issue #117 read properties first
//解析properties
propertiesElement(root.evalNode("properties"));
//解析settings
loadCustomVfs(settings);
//解析typeAliases,类型别名
typeAliasesElement(root.evalNode("typeAliases"));
//解析插件
pluginElement(root.evalNode("plugins"));
//解析对象工厂
objectFactoryElement(root.evalNode("objectFactory"));
//解析对象包装工厂
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
//解析reflectorFactory
reflectorFactoryElement(root.evalNode("reflectorFactory"));
//把settings里各个所有设置设置到configruation上
settingsElement(settings);
// read it after objectFactory and objectWrapperFactory issue #631
//解析environments
environmentsElement(root.evalNode("environments"));
//解析databaseIdProvider
databaseIdProviderElement(root.evalNode("databaseIdProvider"));
//解析typeHandlers,类型处理器
typeHandlerElement(root.evalNode("typeHandlers"));
//解析mappers
mapperElement(root.evalNode("mappers"));
} catch (Exception e) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
}
}
Mybatis会把配置文件的所有信息都保存在Configuration对象中,并返回包含了configuration的DefualtSqlSessionFactoryd对象
configuration对象:
主要过程:
解析xml的每一个信息保存在Configuration中,返回包含Configuration的DefaultSqlSessionFactory;
SqlSession session = factory.openSession();
//class:DefaultSqlSessionFactory
@Override
public SqlSession openSession() {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
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);
//构建DefaultSqlSession对象并返回
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();
}
}
执行器Executor创建过程:
//根据传入的ExecutorType来构建不同的Executor,可以在配置文件中配置,默认是SIMPLE
//final Executor executor = configuration.newExecutor(tx, execType);
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
executor = new SimpleExecutor(this, transaction);
}
//如果要求缓存,生成另一种CachingExecutor(默认就是有缓存),装饰者模式,所以默认都是返回CachingExecutor
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
//此处调用插件,通过插件可以改变Executor行为,采用的是责任链模式,来产生代理对象
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
SqlSession对象中包含configuration和executor
主要过程:
1、根据ExecutorType创建Executor,默认是SIMPLE类型的,但因为cacheEnabled默认是为true的,所以实际上生成的是CachingExecutor,里面包含了一个Executor,使用了装饰者模式;
2、返回一个DefaultSqlSession对象,该对象包含Configuration和Executor;