MyBatis有几个非常重要的接口和类:Configuration、SqlSessionFactory、SqlSession、Executor、MappedStatement、StatementHandler、ResultHandler
Configuration:
Configuration类是用于管理MyBatis全局配置文件的关系类,其中包括数据源(Environment->DataSource)、Mapper.xml配置文件(Map
SqlSessionFactory:
SqlSessionFactory是Session的管理工厂接口,用于开启SqlSession。
SqlSession:
SqlSession中包含了许多面向开发者的调用方法,如selectOne()、selectList()、delete()、update()等方法。
Executor:
Executor接口用于执行数据库操作,其有基本执行器(BaseExecutor)和缓存执行(CachingExecutor)器两个实现类。SqlSession内部通过Executor的query()、update()、rollback()、commit()等方法执行对数据库数据和事务的操作。
MappedStatement:
MappedStatement是Mapper.xml配置文件的封装对象,其中包含SQL语句(SqlSource)、输入参数(ParameterMap)、输出结果集(List)等。
StatementHandler:
StatementHandler接口具体操作数据库相关的Handler,提供query()、getBoundSql()等方法。
ResultHandler:
ResultHandler接口用于操作数据库返回结果。
public class TestDemo {
private SqlSession session;
@Before
public void before() throws IOException {
// 指定MyBatis全局配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 构建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 开启SqlSession
session = sqlSessionFactory.openSession();
}
@Test
public void test1() {
// 调用SqlSession自带查询方法
User user = session.selectOne("com.sk.test.mapper.UserMapper.selectUser", 1);
System.out.println(user);
}
@Test
public void test2() {
// 通过Mapper对象和Mapper.xml调用查询
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUser(1);
System.out.println(user);
}
}
从上面的示例代码可以看出,MyBatis的使用主要分为两步:开启SqlSession和执行数据库操作,接下来从源码对这两步过程进行分析。
开启SqlSession过程中主要通过SqlSessionFactoryBuilder的build()方法来构建SqlSessionFactory,然后再通过SqlSessionFactory的openSession()方法开启SqlSession,其中关键部分在build()和openSession()两个方法中。
通过查看build()方法的源码可以看到在build方法中首先创建了一个XMLConfigBuilder对象,该对象用于读取MyBatis的全局配置文件,然后再通过parse()方法返回Configuration对象。parse()方法代码如下
parse方法中通过调用内部的parseConfiguration()方法来进行具体的XML文件解析。在获取到解析后的Configuration对象之后SqlSessionFactoryBuilder将Configuration对象作为参数再调用build()方法返回DefaultSqlSessionFactory对象,而DefaultSqlSessionFactory为SqlSessionFactory的实现类之一。
由于build()方法返回的是DefaultSqlSessionFactory对象,因此在调用openSession()时实际调用的是DefaultSqlSessionFactory.openSession()。在DefaultSqlSessionFactory.openSession()中,实际调用内部的openSessionFromDataSource(),openSessionFromDataSource源码如下
可以看到openSessionFromDataSource()方法,可以看到在openSessionFromDataSource方法中做了
以下几件事情:
其中,创建执行器的newExecutor()源码如下
这里默认使用的执行器类型是Simple类型的(在Configuration类中可以查看),所以在判断执行器类型是会创建SimpleExecutor对象,但是下面这句话判断是否开启一级缓存时会将SimpleExecutor对象委托给CachingExecutor,最终返回CachingExecutor对象,因此可以看出MyBatis默认开启一级缓存。
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
通过上面的源码分析可以得到以下开启SqlSession的方法调用链
## 获取SqlSessionFactory
├─org.apache.ibatis.session.SqlSessionFactoryBuilder#build(java.io.InputStream)
├─org.apache.ibatis.session.SqlSessionFactoryBuilder#build(java.io.InputStream, java.lang.String, java.util.Properties)
└─org.apache.ibatis.builder.xml.XMLConfigBuilder#parse
└─org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration
└─org.apache.ibatis.session.SqlSessionFactoryBuilder#build(org.apache.ibatis.session.Configuration)
## 开启SqlSession
├─org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSession()
├─org.apache.ibatis.session.defaults.DefaultSqlSessionFactory#openSessionFromDataSource
└─org.apache.ibatis.session.Configuration#newExecutor(org.apache.ibatis.transaction.Transaction, org.apache.ibatis.session.ExecutorType)
└─return new DefaultSqlSession(configuration, executor, autoCommit)
MyBatis源码分析——MyBatis核心组件和开启SqlSession
MyBatis源码分析——使用SqlSession操作数据库
MyBatis源码分析——调用Mapper接口方法执行SQL
MyBatis源码分析——使用注解执行SQL