
前言
本篇文章将会从MyBatis底层实现着手,来分析MyBatis的4大核心对象。
MyBatis四大核心对象
MyBatis完成一次数据库操作需要经过哪些步骤,如下图所示:

可以得出主要分为以下步骤:
1、加载配置文件
2、获取SqlSessionFactoryBuiler对象
3、通过SqlSessionFactoryBuiler和配置文件流来获取SqlSessionFactory对象
4、利用SqlSessionFactory对象来打开一个SqlSession
5、通过SqlSession来获得对应的Mapper对象
6、通过Mapper对象调用对应接口来查询数据库
从这些步骤我们可以看到,MyBatic完成一次数据库操作主要有4大核心对象:SqlSessionFactoryBuiler,SqlSessionFactory,SqlSession和Mapper。
01
SqlSessionFactory

SqlSessionFactoryBuiler内使用到了建造者模式
1.1
(2+1)方法分析
请看下图,前面三个方法最终都调用了第4个方法,所以实际上就是一个方法

在看下面这个其实也是一回事,有三个方法最终也是调用了同一个方法:

所以这两个方法就对应了2+1方法中的2。
上面图中也可以看到,这2个方法在将配置文件解析成一个Java配置类Configuration之后,又同时调用了另一个方法build(Configuration config),而这个方法也没做什么事,就是把配置类传进去返回了一个DefaultSqlSessionFactory对象,这个对象就是SqlSessionFactory的实现类

String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
但是其实我们同样可以采用下面的方式才获取SqlSessionFactory对象:
Reader reader = Resources.getResourceAsReader(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
这两个方法的唯一区别就是在这里,另外两个参数都是一样的。
String environment:

Properties properties:上图中我们下面的dataSource内的属性没有直接输入,而是采用了${jdbc.driver}来配置,而这些属性的值我们可以单独维护在一个properties文件内。

然后代码中就可以这么改写:
Reader reader = Resources.getResourceAsReader(resource);Properties properties = Resources.getResourceAsProperties("db.properties");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader,properties);
采用这种方式之后,mybatis-config.xml文件可以直接用${}来取值了。当然其实还有一种更简单的方式,那就是直接在mybatis-config.xml引入properties文件,这样就不用在代码中去解析properties文件了:
<properties resource="db.properties"></properties>

Configuration congiguration = new Configuration();congiguration.setDatabaseId("xxx");congiguration.setCacheEnabled(false);SqlSessionFactory sqlSessionFactory1 = new SqlSessionFactoryBuilder().build(congiguration);
1.2
InputStream和Reader
02
SqlSessionFactory
2.1
DefaultSqlSessionFactory
DefaultSqlSessionFactory是SqlSessionFactory默认的实现类,现在用的也基本上就是它。这个类提供了8个方法用来获取SqlSession对象。这个截图不太好截,为了方便对比,我把方法列举出来:
SqlSession openSession();SqlSession openSession(boolean autoCommit);SqlSession openSession(TransactionIsolationLevel level);SqlSession openSession(ExecutorType execType,TransactionIsolationLevel level);SqlSession openSession(ExecutorType execType);SqlSession openSession(ExecutorType execType, boolean autoCommit);SqlSession openSession(Connection connection);SqlSession openSession(ExecutorType execType, Connection connection);


从上面的两个方法截图中很明显可以看到,这两个方法基本一样,唯一的区别是openSessionFromConnection方法是从Connection对象中获取当前会话是否需要开启自动提交。
Executor
2.2
SqlSessionManager

SqlSession

四大对象生命周期

总结




