Mybatis的核心组件

(一)主要构件



1. SqlSession 作为MyBatis工作的主要顶层API,表示和数据库交互的会话,完成必要数据库增删改查功能。
2. Executor MyBatis执行器,是MyBatis 调度的核心,负责SQL语句的生成和查询缓存的维护。
3. StatementHandler 封装了JDBC Statement操作,负责对JDBC statement 的操作,如设置参数、将Statement结果集转换成List集合。
4. ParameterHandler 负责对用户传递的参数转换成JDBC Statement 所需要的参数。
5. ResultSetHandler 负责将JDBC返回的ResultSet结果集对象转换成List类型的集合。
6. TypeHandler 负责java数据类型和jdbc数据类型之间的映射和转换。
7. MappedStatement MappedStatement维护了一条节点的封装。
8. SqlSource 负责根据用户传递的parameterObject,动态地生成SQL语句,将信息封装到BoundSql对象中,并返回。
9. BoundSql 表示动态生成的SQL语句以及相应的参数信息。
10. Configuration MyBatis所有的配置信息都维持在Configuration对象之中。


(二)SqlSessionFactoryBuilder


SqlSessionFactoryBuilder读取Mybatis核心配置信息创建SqlSessionFactory(会话工厂)

使用的是建造者模式:
实现SQLSessionFactory其实是一个非常复杂的过程,它要去解析核心配置文件Mybatis-config.xml,然后去解析mapping.xml文件获取很多的信息填充到内存里面来,所以用建造者模式.

SqlSessionFactoryBuilder它是方法级别生命周期,也就是说,它是一个局部变量.SqlSessionFactoryBuilder建造的SqlSessionFactory是一个专门生产SqlSession的,SqlSession是一次数据库的连接的包装(数据库的会话)


InputStream inputStream = Resources.getResourceAsStream(“MyBatisCofig.xml”);
// 2. 根据主配置文件创建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

这个类可以被实例化、使用和丢弃(生命周期只存在于方法体内),一旦创建了 SqlSessionFactory,就不再需要它了(完成了使命,)。因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。你可以重用 SqlSessionFactoryBuilder 来创建多个SqlSessionFactory 实例,但是最好还是不要让其一直存在以保证所有的 XML 解析资源开放给更重要的事情。



(三)SqlSessionFactory


SqlSessionFactory(根据SqlSessionFactoryBuilder创建会话工厂,是Mybatis核心)

它是用来创建sqlSession对象的,而sqlSession用来操作数据库的。
SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在(生命周期与应用的生命周期相同,同时存在于整个应用运行时,并且同时只存在一个对象实例,是单例),没有任何理由对它进行清除或重建。使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。



SqlSessionFactory一旦创建成功就是一个单例的对象,它的职责就是不断的产生SqlSession对象

(四)SqlSession


SqlSession(根据SqlSessionFactory创建会话)
SqlSession代表一次数据库连接,一般通过调用Mapper访问数据库,也可以直接发送sql执行,线程不安全,要保证线程独享(方法级)

简述:mybatis所有的sql都是通过sqlsession执行,sqlsession中封装了对数据库的操作(增删改查)

作用:1)获取映射器,让映射器通过命名空间和方法名称找到对应的SQL,发送给数据库执行后返回结果;2)通过update、insert、select、delete等方法,带上SQL的id来操作在XML中配置好的SQL,从而完成工作,与此同时它也支持事务,通过commit、rollback方法提交或者回滚事务。

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。也绝不能将 SqlSession 实例的引用放在任何类型的管理作用域中,比如 Serlvet 架构中的 HttpSession。如果你现在正在使用一种 Web 框架,要考虑 SqlSession 放在一个和 HTTP 请求对象相似的作用域中。换句话说,每次收到的 HTTP 请求,就可以打开一个 SqlSession,返回一个响应,就关闭它。这个关闭操作是很重要的,你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭。

(五)SQLMapper


SQL Mapper:由一个Java接口和XML文件组成,包含了要执行的SQL语句和结果集映射规则。方法级别生命周期;


(六)Executor

Executor是对JDBC的Stament对象的封装,每次执行完了一次会话的时候就会给Stament对象关闭掉.



Mybatis执行器对象,被SqlSession对象持有

SqlSession会操作我们的Executor执行器对数据库进行增删改查操作.


有下面Executor执行器:

BaseExecutor
SimpleExecutor
BatchExecutor
ReuseExecutor



(七)StatementHandler


BaseStatementHandler
SimpleStatementHandler
PreparedStatementHandler
CallableStatementHandler

操作关系型数据库,会处理我们方法里面的入参,和数据库返回的结果.
封装了jdbc的 statement的操作


(八)MappedStatement


MappedStatement 维护了一条节点的封装,包括了 SQL 信息、入参信息、出参信息.

里面主要的东西是SqlSource , BoundSql.


成员属性

private String resource;
private Configuration configuration;
private String id;
private Integer fetchSize;
private Integer timeout;
private StatementType statementType;
private ResultSetType resultSetType;
private SqlSource sqlSource;
private Cache cache;
private ParameterMap parameterMap;
private List resultMaps;
private boolean flushCacheRequired;
private boolean useCache;
private boolean resultOrdered;
private SqlCommandType sqlCommandType;
private KeyGenerator keyGenerator;
private String[] keyProperties;
private String[] keyColumns;
private boolean hasNestedResultMaps;
private String databaseId;
private Log statementLog;
private LanguageDriver lang;
private String[] resultSets;

(九)ParameterHandler

DefaultParameterHandler
把用户传递的参数转换成 JDBC Statement 所需要的参数

(十)ResultSetHandler

DefaultResultSetHandler
把 JDBC 返回的 ResultSet 结果集对象转换成 List 类型的集合