1,读取配置文件,生成连接
2,读取sql语句,生成sql语句——执行,得到结果,组装到结果集中
1,读取配置文件,生成连接
String resource = "mybatis.config.xml";
Reader reader = Resources.getResourceAsReader(resource); \\读取到配置文件,将文件以输入流的方式读取到内存中
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(reader);
SqlSession ss = ssf.openSession();
SqlSessionFactoryBuilder类中重载了9个build方法。前4个的配置输入是 Reader 。后4个的配置输入是 InputStreatm 。最后一个直接返回默认的连接工厂类。
两个生成连接工厂的方法写法几乎完全一致,通过创建一个XMLConfigBuilder对象,执行其parse()方法得到一个Configuration,把这个Configuration传入最后一个构造方法生成 连接工厂类
public SqlSessionFactory build(Reader reader) {
return this.build((Reader)reader, (String)null, (Properties)null);
}
public SqlSessionFactory build(Reader reader, String environment) {
return this.build((Reader)reader, environment, (Properties)null);
}
public SqlSessionFactory build(Reader reader, Properties properties) {
return this.build((Reader)reader, (String)null, properties);
}
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
SqlSessionFactory var5;
。。。
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
var5 = this.build(parser.parse());
。。。
return var5;
}
public SqlSessionFactory build(InputStream inputStream) {
return this.build((InputStream)inputStream, (String)null, (Properties)null);
}
public SqlSessionFactory build(InputStream inputStream, String environment) {
return this.build((InputStream)inputStream, environment, (Properties)null);
}
public SqlSessionFactory build(InputStream inputStream, Properties properties) {
return this.build((InputStream)inputStream, (String)null, properties);
}
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
SqlSessionFactory var5;
。。。
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
var5 = this.build(parser.parse());
。。。
return var5;
}
public SqlSessionFactory build(Configuration config) {return new DefaultSqlSessionFactory(config);}
XMLConfigBuilder的作用就是解析mybatis的配置文件,然后根据配置生成连接工厂。
XMLConfigBuilder有以下4个私有属性
private boolean parsed; //是否解析过
private final XPathParser parser; //配置文件路径
private String environment; //配置文件里的环境,没有指定就使用默认的
private final ReflectorFactory localReflectorFactory;
XMLConfigBuilder中重载了多个构造方法以根据不同参数来构造对象,所有的构造方法都指向了一个私有的构造方法。这里需要一个XPathParser对象,以及前面传过来的两个参数
public XMLConfigBuilder(Reader reader, String environment, Properties props) {
this(new XPathParser(reader, true, props, new XMLMapperEntityResolver()), environment, props);
}
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());
this.localReflectorFactory = new DefaultReflectorFactory(); //反射工厂,用来返回sql中指定的类信息
ErrorContext.instance().resource("SQL Mapper Configuration");
this.configuration.setVariables(props);
this.parsed = false; //默认没有解析过,解析之后这里变为true,只能解析一次
this.environment = environment; //配置文件中的环境
this.parser = parser;
}
parse()方法是比较重要的。首先判断是否解析过配置,这里只能解析一次(解析一次就得到了全部信息,貌似就没必要进行第二次了,浪费资源)。解析配置调用parseConfiguration()方法解析配置文件
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"));
return this.configuration;
}
}
parseConfiguration方法是读取配置文件保存到类中的核心方法。
在此,将配置配置文件中的各个标签下的属性都读取到类中保存。该类是Configuration的一个实体类,并且是XMLConfigBuilder的一个 protected 的属性(继承自BaseBuilder)。得到的这个Configuration最终作为参数传入SqlSessionFactoryBuilder的构造方法中,得到连接工厂类
private void parseConfiguration(XNode root) {
try {
this.propertiesElement(root.evalNode("properties"));
Properties settings = this.settingsAsProperties(root.evalNode("settings"));
this.loadCustomVfs(settings);
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(settings);
this.environmentsElement(root.evalNode("environments"));
this.databaseIdProviderElement(root.evalNode("databaseIdProvider"));
this.typeHandlerElement(root.evalNode("typeHandlers"));
this.mapperElement(root.evalNode("mappers"));
} catch (Exception var3) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + var3, var3);
}
}
DefaultSqlSessionFactory类中只有一个构造方法,一堆重载的openSession()方法,而最终指向的有两个私有方法,这两个私有方法最终都返回了DefaultSqlSession(实现了SqlSession接口)。Session创建成功
public class DefaultSqlSessionFactory implements SqlSessionFactory {
private final Configuration configuration;
public DefaultSqlSessionFactory(Configuration configuration) {
this.configuration = configuration;
}
//这里是一堆重载的 openSession 方法
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
DefaultSqlSession var8;
try {
Environment environment = this.configuration.getEnvironment();
TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
Executor executor = this.configuration.newExecutor(tx, execType);
var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);
} catch (Exception var12) {
this.closeTransaction(tx);
throw ExceptionFactory.wrapException("Error opening session. Cause: " + var12, var12);
} finally {
ErrorContext.instance().reset();
}
return var8;
}
private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {
DefaultSqlSession var8;
try {
boolean autoCommit;
try {
autoCommit = connection.getAutoCommit();
} catch (SQLException var13) {
autoCommit = true;
}
Environment environment = this.configuration.getEnvironment();
TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
Transaction tx = transactionFactory.newTransaction(connection);
Executor executor = this.configuration.newExecutor(tx, execType);
var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);
} catch (Exception var14) {
throw ExceptionFactory.wrapException("Error opening session. Cause: " + var14, var14);
} finally {
ErrorContext.instance().reset();
}
return var8;
}
}
第一次写,权当自己做的笔记吧!