在了解mybatis之前,我们先来看看原始jdbc操作数据库需要哪些步骤:
Class.forName("com.mysql.jdbc.Driver"); //1.加载驱动
Connection con = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/kkb","root","123"
); //2.获取数据库链接
con.setAutoCommit(false)
PreparedStatement ps = con.preparedStatement(sql); // 3.得到数据库操作对象
ps.setInt(); // 4.设置参数
ps.setString();
try{
int num= ps.executeUpdate();
ResultSet rs= ps.executeQuery(); //5.执行sql,得到结果
ps.executeBatch();
con.commit(); //6. 提交事物
}catch(SQLException ex){
con.rollback();
}
con.close(); //7.关闭链接
mybatis作为一个数据持久层框架,说白了就是对上面几个步骤的封装,然我们只需要关心sql的编写,其它的事,都是一些公共的操作,我们只需要简单的配置,它就可以帮我们完成了。
下面对源码的解析,大体的方向也就是看mybatis对应上述的步骤,都是怎么封装的。
1.加载配置文件,生成Configuration对象
Configuration对象是mybatis配置在内存中的载体。
这里的源码,多余的内容被我删了,只留下了主要的处理逻辑。
//SqlSessionFactoryBuilder.build()方法,该方法返回SqlSessionFactory(工厂模式)
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
//reader 配置文件的数据流
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
return build(parser.parse());
}
}
public Configuration parse() {
//解析配置文件的方法
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
parseConfiguration(parser.evalNode("/configuration"));
return configuration;
}
//具体解析配置,然后设置到Configuration对象中
//这里采用了建造者模式,一步步完善Configuration的属性
private void parseConfiguration(XNode root) {
try {
//issue #117 read properties first
propertiesElement(root.evalNode("properties"));
Properties settings = settingsAsProperties(root.evalNode("settings"));
loadCustomVfs(settings);
typeAliasesElement(root.evalNode("typeAliases"));
pluginElement(root.evalNode("plugins"));
objectFactoryElement(root.evalNode("objectFactory"));
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
reflectorFactoryElement(root.evalNode("reflectorFactory"));
settingsElement(settings);
// read it after objectFactory and objectWrapperFactory issue #631
environmentsElement(root.evalNode("environments"));
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);
}
}
2.创建执行器对象Executor
Executor是个接口,它有两个实现类BaseExecutor和CachingExecutor
- BaseExecutor(适配器 模式)有三个子类:
* SimpleExecutor 普通执行器
* ReuseExecutor 可重用执行器
* BatchExecutor 批量执行器
具体看下面源码,会根据不同情况创建不同的Executor.
通过第一步的SqlSessionFactory.openSession()就会创建一个SqlSession,
下面看看openSession()干了啥 (采用的DefaultSqlSessionFactory的openSession())
private SqlSession openSessionFromDataSource(ExecutorType execType