1. 核心层次

2. SqlSession

先从顶层的SqlSession接口开始说起。SqlSession是MyBatis提供的面向用户的API,表示和数据库的会话对象,用于完成对数据库的一系列CRUD操作以及获取mappers和管理事务等。

public interface SqlSession extends Closeable {

  /**
* Retrieve a single row mapped from the statement key.
* @param <T> the returned object type
* @param statement
* the statement
* @return Mapped object
*/
<T> T selectOne(String statement); /**
* Retrieve a single row mapped from the statement key and parameter.
* @param <T> the returned object type
* @param statement Unique identifier matching the statement to use.
* @param parameter A parameter object to pass to the statement.
* @return Mapped object
*/
<T> T selectOne(String statement, Object parameter); /**
* Retrieve a list of mapped objects from the statement key.
* @param <E> the returned list element type
* @param statement Unique identifier matching the statement to use.
* @return List of mapped object
*/
<E> List<E> selectList(String statement); /**
* Retrieve a list of mapped objects from the statement key and parameter.
* @param <E> the returned list element type
* @param statement Unique identifier matching the statement to use.
* @param parameter A parameter object to pass to the statement.
* @return List of mapped object
*/
<E> List<E> selectList(String statement, Object parameter); /**
* Retrieve a list of mapped objects from the statement key and parameter,
* within the specified row bounds.
* @param <E> the returned list element type
* @param statement Unique identifier matching the statement to use.
* @param parameter A parameter object to pass to the statement.
* @param rowBounds Bounds to limit object retrieval
* @return List of mapped object
*/
<E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds); /**
* The selectMap is a special case in that it is designed to convert a list
* of results into a Map based on one of the properties in the resulting
* objects.
* Eg. Return a of Map[Integer,Author] for selectMap("selectAuthors","id")
* @param <K> the returned Map keys type
* @param <V> the returned Map values type
* @param statement Unique identifier matching the statement to use.
* @param mapKey The property to use as key for each value in the list.
* @return Map containing key pair data.
*/
<K, V> Map<K, V> selectMap(String statement, String mapKey); /**
* The selectMap is a special case in that it is designed to convert a list
* of results into a Map based on one of the properties in the resulting
* objects.
* @param <K> the returned Map keys type
* @param <V> the returned Map values type
* @param statement Unique identifier matching the statement to use.
* @param parameter A parameter object to pass to the statement.
* @param mapKey The property to use as key for each value in the list.
* @return Map containing key pair data.
*/
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey); /**
* The selectMap is a special case in that it is designed to convert a list
* of results into a Map based on one of the properties in the resulting
* objects.
* @param <K> the returned Map keys type
* @param <V> the returned Map values type
* @param statement Unique identifier matching the statement to use.
* @param parameter A parameter object to pass to the statement.
* @param mapKey The property to use as key for each value in the list.
* @param rowBounds Bounds to limit object retrieval
* @return Map containing key pair data.
*/
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds); /**
* A Cursor offers the same results as a List, except it fetches data lazily using an Iterator.
* @param <T> the returned cursor element type.
* @param statement Unique identifier matching the statement to use.
* @return Cursor of mapped objects
*/
<T> Cursor<T> selectCursor(String statement); /**
* A Cursor offers the same results as a List, except it fetches data lazily using an Iterator.
* @param <T> the returned cursor element type.
* @param statement Unique identifier matching the statement to use.
* @param parameter A parameter object to pass to the statement.
* @return Cursor of mapped objects
*/
<T> Cursor<T> selectCursor(String statement, Object parameter); /**
* A Cursor offers the same results as a List, except it fetches data lazily using an Iterator.
* @param <T> the returned cursor element type.
* @param statement Unique identifier matching the statement to use.
* @param parameter A parameter object to pass to the statement.
* @param rowBounds Bounds to limit object retrieval
* @return Cursor of mapped objects
*/
<T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds); /**
* Retrieve a single row mapped from the statement key and parameter
* using a {@code ResultHandler}.
* @param statement Unique identifier matching the statement to use.
* @param parameter A parameter object to pass to the statement.
* @param handler ResultHandler that will handle each retrieved row
*/
void select(String statement, Object parameter, ResultHandler handler); /**
* Retrieve a single row mapped from the statement
* using a {@code ResultHandler}.
* @param statement Unique identifier matching the statement to use.
* @param handler ResultHandler that will handle each retrieved row
*/
void select(String statement, ResultHandler handler); /**
* Retrieve a single row mapped from the statement key and parameter using a {@code ResultHandler} and
* {@code RowBounds}.
*
* @param statement
* Unique identifier matching the statement to use.
* @param parameter
* the parameter
* @param rowBounds
* RowBound instance to limit the query results
* @param handler
* ResultHandler that will handle each retrieved row
*/
void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler); /**
* Execute an insert statement.
* @param statement Unique identifier matching the statement to execute.
* @return int The number of rows affected by the insert.
*/
int insert(String statement); /**
* Execute an insert statement with the given parameter object. Any generated
* autoincrement values or selectKey entries will modify the given parameter
* object properties. Only the number of rows affected will be returned.
* @param statement Unique identifier matching the statement to execute.
* @param parameter A parameter object to pass to the statement.
* @return int The number of rows affected by the insert.
*/
int insert(String statement, Object parameter); /**
* Execute an update statement. The number of rows affected will be returned.
* @param statement Unique identifier matching the statement to execute.
* @return int The number of rows affected by the update.
*/
int update(String statement); /**
* Execute an update statement. The number of rows affected will be returned.
* @param statement Unique identifier matching the statement to execute.
* @param parameter A parameter object to pass to the statement.
* @return int The number of rows affected by the update.
*/
int update(String statement, Object parameter); /**
* Execute a delete statement. The number of rows affected will be returned.
* @param statement Unique identifier matching the statement to execute.
* @return int The number of rows affected by the delete.
*/
int delete(String statement); /**
* Execute a delete statement. The number of rows affected will be returned.
* @param statement Unique identifier matching the statement to execute.
* @param parameter A parameter object to pass to the statement.
* @return int The number of rows affected by the delete.
*/
int delete(String statement, Object parameter); /**
* Flushes batch statements and commits database connection.
* Note that database connection will not be committed if no updates/deletes/inserts were called.
* To force the commit call {@link SqlSession#commit(boolean)}
*/
void commit(); /**
* Flushes batch statements and commits database connection.
* @param force forces connection commit
*/
void commit(boolean force); /**
* Discards pending batch statements and rolls database connection back.
* Note that database connection will not be rolled back if no updates/deletes/inserts were called.
* To force the rollback call {@link SqlSession#rollback(boolean)}
*/
void rollback(); /**
* Discards pending batch statements and rolls database connection back.
* Note that database connection will not be rolled back if no updates/deletes/inserts were called.
* @param force forces connection rollback
*/
void rollback(boolean force); /**
* Flushes batch statements.
* @return BatchResult list of updated records
* @since 3.0.6
*/
List<BatchResult> flushStatements(); /**
* Closes the session.
*/
@Override
void close(); /**
* Clears local session cache.
*/
void clearCache(); /**
* Retrieves current configuration.
* @return Configuration
*/
Configuration getConfiguration(); /**
* Retrieves a mapper.
* @param <T> the mapper type
* @param type Mapper interface class
* @return a mapper bound to this SqlSession
*/
<T> T getMapper(Class<T> type); /**
* Retrieves inner database connection.
* @return Connection
*/
Connection getConnection();
}

SqlSession接口一共有两个实现类,分线程不安全的DefaultSqlSession和线程安全的SqlSessionManager

SqlSessionManager比较特殊,它不仅仅是实现SqlSession,还实现了SqlSessionFactory接口。他其实是相于把两者结合起来,用了一个ThreadLocal来保存每次的SqlSession来实现线程安全,运用JDK动态代理来控制每次会话的事务处理,从ThreadLocal中读取SqlSession用来复用,避免多次创建的资源浪费,享元模式?

这边只是先大概的讲一讲,其实SqlSessionManager就是一个组合模式罢了,走的还是默认操作这一套,只是做了套了一层壳子罢了,留在后面细讲。

2. DefaultSqlSession

DefaultSqlSessionSqlSession默认实现类。SqlSession通过工厂SqlSessionFactory创建。而SqlSessionFactory工厂的默认实现类是DefaultSqlSessionFactory。而DefaultSqlSessionFactory是从SqlSessionFactoryBuilder中生成的。

  public class SqlSessionFactoryBuilder {

  public SqlSessionFactory build(Reader reader) {
return build(reader, null, null);
} public SqlSessionFactory build(Reader reader, String environment) {
return build(reader, environment, null);
} public SqlSessionFactory build(Reader reader, Properties properties) {
return build(reader, null, properties);
} public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
} public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream, null, null);
} public SqlSessionFactory build(InputStream inputStream, String environment) {
return build(inputStream, environment, null);
} public SqlSessionFactory build(InputStream inputStream, Properties properties) {
return build(inputStream, null, properties);
} public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
} public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}

这里用到工厂模式和建造者模式,这两个模式其实很容易搞混,他们都属于设计模式中的创建型模式。

区别在于:

1.工厂模式一般都是创建一个产品,注重的是把这个产品创建出来就行,只要创建出来,不关心这个产品的组成细节。

2.建造者模式也是创建一个产品,但是不仅要把这个产品创建出来,还要关系这个产品的组成细节。

SqlSessionFactoryBuilder就提供了许多不同的方法用来生成SqlSessionFactory

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader, props);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader, "development-hsql")

Mybatis3源码笔记(二)SqlSession的更多相关文章

  1. Mybatis3源码笔记(六)SqlSession执行过程

    前几篇大致分析了初始化的过程,今天打算走一个SqlSession具体执行过程. @Test void shouldSelectAllAuthors() { try (SqlSession sessio ...

  2. jQuery源码笔记(二):定义了一些变量和函数 jQuery = function(){}

    笔记(二)也分为三部分: 一. 介绍: 注释说明:v2.0.3版本.Sizzle选择器.MIT软件许可注释中的#的信息索引.查询地址(英文版)匿名函数自执行:window参数及undefined参数意 ...

  3. Tomcat8源码笔记(二)Bootstrap启动

    TOMCAT源码调试入口是Bootstrap类的main方法,我的启动参数VM: -Dcatalina.home=E:/Tomcat_Source_Code/apache-tomcat-8.0.53- ...

  4. Mybatis3源码笔记(一)环境搭建

    1. 源码下载 地址:https://github.com/mybatis/mybatis-3.git. 国内访问有时确实有点慢,像我就直接先fork.然后从git上同步到国内的gitte上,然后在i ...

  5. Mybatis3源码笔记(八)小窥MyBatis-plus

    前言 Mybatis-Plus是一个 MyBatis增强工具包,简化 CRUD 操作,在 MyBatis 的基础上只做增强不做改变,为简化开发.提高效率而生,号称无侵入,现在开发中比较常用,包括我自己 ...

  6. mybatis 源码学习(二)sqlsession

    mybatis 中的sqlsession是一个非常重要的类.上篇我们分析了sessionfactory初始化配置文件,我们继续分析sessionfactory拿到会话进行的操作. 看这里.getMap ...

  7. Mybatis3源码笔记(七)Plugin

    1.Mybatis3的插件其实主要是用到了责任链和动态代理两种模式相结合而生成的.下面我们看一个例子,在执行所有update操作时,执行一个小小的测试输出. @Intercepts({@Signatu ...

  8. Mybatis3源码笔记(四)Configuration(续)

    1.pluginElement(root.evalNode("plugins")) 解析plugins节点(注册interceptorChain里记录对应的拦截器) private ...

  9. Mybatis3源码笔记(三)Configuration

    1. XMLConfigBuilder 上一篇大致介绍了SqlSession的生成.在DefaultSqlSessionFactory的构造函数中就提到了Configuration这个对象.现在我们来 ...

随机推荐

  1. js异步回调Async/Await与Promise区别 新学习使用Async/Await

    Promise,我们了解到promise是ES6为解决异步回调而生,避免出现这种回调地狱,那么为何又需要Async/Await呢?你是不是和我一样对Async/Await感兴趣以及想知道如何使用,下面 ...

  2. 修改vs模板抬头\Common7\IDE\ItemTemplates\CSharp\Code\2052\Class

    //************************************************************************************************** ...

  3. 手把手教你gitlab汉化

    详细教程如下: 一.在Github上 https://gitlab.com/xhang/gitlab/-/tags 下载对应的版本到服务器中 这种-zh结尾的才是汉化包,下载速度可能比较慢,有条件的可 ...

  4. DOM的理解

    https://www.cnblogs.com/djtang/p/11538420.html  dom的理解 https://blog.csdn.net/jiuqiyuliang/article/de ...

  5. loadrunner学习笔记一

    这篇笔记主要是针对一个具体的loadrunner脚本里面出现的方法进行解释,具体脚本如下: ` Action() { char *transactionName = "Test"; ...

  6. 原生js日历选择器,学习js面向对象开发日历插件

    在web开发过程中经常会碰到需要选择日期的功能,一般的操作都是在文本框点击,然后弹出日历选择框,直接选择日期就可以在文本框显示选择的日期.开发好之后给用户使用是很方便,但如果每一个日历选择器都要临时开 ...

  7. python引用C++ DLL文件若干解释及示例

    python引用C++ DLL文件若干解释及示例 首先说一下,python不支持C++的DLL,但是支持C的DLL:C++因为和C兼容可以编译为C的DLL,这是下面文章的背景与前提 首先我这儿的示例使 ...

  8. 测试平台系列(2) 给Pity添加配置

    给Pity添加配置 回顾 还记得上篇文章创立的「Flask」实例吗?我们通过这个实例,给根路由 「/」 绑定了一个方法,从而使得用户访问不同路由的时候可以执行不同的方法. 配置 要知道,在一个「Web ...

  9. 前端坑多:使用js模拟按键输入的踩坑记录

    坑 一开始在Google搜索了一番,找到了用jQuery的方案,代码量很少,看起来很美好很不错,结果,根本没用-- 我反复试了这几个版本: var e = $.Event('keyup') e.key ...

  10. 危害api收集

    以下每一条代码,无论其通过什么方式被调用,在哪个类里被调用,传入什么参数,都具有唯一不变性(在逆向出来的的smali文件里),故可以作为匹配的凭证.     网络操作相关: Ljava/net/URL ...