myBatis源码学习之SqlSession
在上一篇文章中SqlSessionFactory介绍了生产SqlSession的工厂,SqlSession是一个接口其具体实现类为DefaultSqlSession,SqlSession接口主要定义了一些增删改查方法,DefaultSQLSession是对SqlSession接口的具体实现。
SqlSession接口源码及注释:
/** * The primary Java interface for working with MyBatis. * Through this interface you can execute commands, get mappers and manage transactions. * * @author Clinton Begin */ public interface SqlSession extends Closeable { /** * Retrieve a single row mapped from the statement key * @param <T> the returned object type * @param 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 and parameter. * @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. */ //将结果转换成map <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. */ //将条件结果转换成map <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. */ //有条件结果及一定行数的数据转换成map <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, 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 * @return Mapped object */ //根据处理器处理检索到的结果 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 * @return Mapped object */ //根据处理器处理检索到的结果 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 rowBounds RowBound instance to limit the query results * @param handler ResultHandler that will handle each retrieved row * @return Mapped object */ //根据处理器处理检索到的结果 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(); }
DefaultSqlSession是各种增删改查接口的具体实现,但最终的sql语句执行是在Executor中的query方法执行的,所以DefaultSqlSession也只是简单的接口封装
DefaulSqlSession源码及注释:
/** * @author Clinton Begin */ public class DefaultSqlSession implements SqlSession { private Configuration configuration; //配置文件生成的对象 private Executor executor;//执行器 private boolean autoCommit;//是否自动提交 private boolean dirty; //构造函数,获取配置文件及执行器等参数 public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) { this.configuration = configuration; this.executor = executor; this.dirty = false; this.autoCommit = autoCommit; } public DefaultSqlSession(Configuration configuration, Executor executor) { this(configuration, executor, false); } public <T> T selectOne(String statement) { return this.<T>selectOne(statement, null); } //获取所有结果但只返回第一个数据 public <T> T selectOne(String statement, Object parameter) { // Popular vote was to return null on 0 results and throw exception on too many. List<T> list = this.<T>selectList(statement, parameter); if (list.size() == 1) { return list.get(0); } else if (list.size() > 1) { //结果大于1就报错 throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size()); } else { return null; } } public <K, V> Map<K, V> selectMap(String statement, String mapKey) { return this.selectMap(statement, null, mapKey, RowBounds.DEFAULT); } public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey) { return this.selectMap(statement, parameter, mapKey, RowBounds.DEFAULT); } //首先获取数据结果列表list,将条件结果转换成map public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) { final List<?> list = selectList(statement, parameter, rowBounds); final DefaultMapResultHandler<K, V> mapResultHandler = new DefaultMapResultHandler<K, V>(mapKey, configuration.getObjectFactory(), configuration.getObjectWrapperFactory()); final DefaultResultContext context = new DefaultResultContext(); for (Object o : list) { context.nextResultObject(o); mapResultHandler.handleResult(context); } Map<K, V> selectedMap = mapResultHandler.getMappedResults(); return selectedMap; } public <E> List<E> selectList(String statement) { return this.selectList(statement, null); } public <E> List<E> selectList(String statement, Object parameter) { return this.selectList(statement, parameter, RowBounds.DEFAULT); } //RowBounds中有两个参数offset和limit,默认offset是0,limit是Integer.MAX_VALUE public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) { try { //通过配置文件的mapper中的id来获取某个具体的增删改查的各种参数 MappedStatement ms = configuration.getMappedStatement(statement); //最终的操作是利用executor执行器来进行sql语句的操作 //wrapCollection(parameter)如果参数类型是collection、list或者array都添加到StrictMap中作为一个参数 //如果不是。。。 List<E> result = executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER); return result; } catch (Exception e) { throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } public void select(String statement, Object parameter, ResultHandler handler) { select(statement, parameter, RowBounds.DEFAULT, handler); } public void select(String statement, ResultHandler handler) { select(statement, null, RowBounds.DEFAULT, handler); } public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) { try { MappedStatement ms = configuration.getMappedStatement(statement); executor.query(ms, wrapCollection(parameter), rowBounds, handler); } catch (Exception e) { throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } //插入操作 public int insert(String statement) { return insert(statement, null); } public int insert(String statement, Object parameter) { return update(statement, parameter); } //更新操作 public int update(String statement) { return update(statement, null); } public int update(String statement, Object parameter) { try { dirty = true; MappedStatement ms = configuration.getMappedStatement(statement); return executor.update(ms, wrapCollection(parameter)); } catch (Exception e) { throw ExceptionFactory.wrapException("Error updating database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } //删除操作 public int delete(String statement) { return update(statement, null); } public int delete(String statement, Object parameter) { return update(statement, parameter); } //提交 public void commit() { commit(false); } public void commit(boolean force) { try { executor.commit(isCommitOrRollbackRequired(force)); dirty = false; } catch (Exception e) { throw ExceptionFactory.wrapException("Error committing transaction. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } public void rollback() { rollback(false); } public void rollback(boolean force) { try { executor.rollback(isCommitOrRollbackRequired(force)); dirty = false; } catch (Exception e) { throw ExceptionFactory.wrapException("Error rolling back transaction. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } public List<BatchResult> flushStatements() { try { return executor.flushStatements(); } catch (Exception e) { throw ExceptionFactory.wrapException("Error flushing statements. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } public void close() { try { executor.close(isCommitOrRollbackRequired(false)); dirty = false; } finally { ErrorContext.instance().reset(); } } public Configuration getConfiguration() { return configuration; } //获得映射器是创建绑定映射语句的接口 public <T> T getMapper(Class<T> type) { return configuration.<T>getMapper(type, this); } public Connection getConnection() { try { return executor.getTransaction().getConnection(); } catch (SQLException e) { throw ExceptionFactory.wrapException("Error getting a new connection. Cause: " + e, e); } } public void clearCache() { executor.clearLocalCache(); } private boolean isCommitOrRollbackRequired(boolean force) { return (!autoCommit && dirty) || force; } //对参数类型是collection、list或者array的类型都放在一个map中 private Object wrapCollection(final Object object) { if (object instanceof List) { StrictMap<Object> map = new StrictMap<Object>(); map.put("list", object); return map; } else if (object != null && object.getClass().isArray()) { StrictMap<Object> map = new StrictMap<Object>(); map.put("array", object); return map; } return object; } public static class StrictMap<V> extends HashMap<String, V> { private static final long serialVersionUID = -5741767162221585340L; @Override public V get(Object key) { if (!super.containsKey(key)) { throw new BindingException("Parameter '" + key + "' not found. Available parameters are " + this.keySet()); } return super.get(key); } } }
myBatis源码学习之SqlSession的更多相关文章
- mybatis 源码学习(二)sqlsession
mybatis 中的sqlsession是一个非常重要的类.上篇我们分析了sessionfactory初始化配置文件,我们继续分析sessionfactory拿到会话进行的操作. 看这里.getMap ...
- mybatis源码学习(一) 原生mybatis源码学习
最近这一周,主要在学习mybatis相关的源码,所以记录一下吧,算是一点学习心得 个人觉得,mybatis的源码,大致可以分为两部分,一是原生的mybatis,二是和spring整合之后的mybati ...
- Mybatis源码解析(四) —— SqlSession是如何实现数据库操作的?
Mybatis源码解析(四) -- SqlSession是如何实现数据库操作的? 如果拿一次数据库请求操作做比喻,那么前面3篇文章就是在做请求准备,真正执行操作的是本篇文章要讲述的内容.正如标题一 ...
- mybatis源码学习:一级缓存和二级缓存分析
目录 零.一级缓存和二级缓存的流程 一级缓存总结 二级缓存总结 一.缓存接口Cache及其实现类 二.cache标签解析源码 三.CacheKey缓存项的key 四.二级缓存TransactionCa ...
- mybatis源码学习:基于动态代理实现查询全过程
前文传送门: mybatis源码学习:从SqlSessionFactory到代理对象的生成 mybatis源码学习:一级缓存和二级缓存分析 下面这条语句,将会调用代理对象的方法,并执行查询过程,我们一 ...
- Mybatis源码学习第六天(核心流程分析)之Executor分析
今Executor这个类,Mybatis虽然表面是SqlSession做的增删改查,其实底层统一调用的是Executor这个接口 在这里贴一下Mybatis查询体系结构图 Executor组件分析 E ...
- mybatis源码学习:插件定义+执行流程责任链
目录 一.自定义插件流程 二.测试插件 三.源码分析 1.inteceptor在Configuration中的注册 2.基于责任链的设计模式 3.基于动态代理的plugin 4.拦截方法的interc ...
- mybatis源码学习(三)-一级缓存二级缓存
本文主要是个人学习mybatis缓存的学习笔记,主要有以下几个知识点 1.一级缓存配置信息 2.一级缓存源码学习笔记 3.二级缓存配置信息 4.二级缓存源码 5.一级缓存.二级缓存总结 1.一级缓存配 ...
- Mybatis源码学习之整体架构(一)
简述 关于ORM的定义,我们引用了一下百度百科给出的定义,总体来说ORM就是提供给开发人员API,方便操作关系型数据库的,封装了对数据库操作的过程,同时提供对象与数据之间的映射功能,解放了开发人员对访 ...
随机推荐
- SQLite 语法(http://www.w3cschool.cc/sqlite/sqlite-syntax.html)
SQLite 语法 SQLite 是遵循一套独特的称为语法的规则和准则.本教程列出了所有基本的 SQLite 语法,向您提供了一个 SQLite 快速入门. 大小写敏感性 有个重要的点值得注意,SQL ...
- Android必知必会-自定义Scrollbar样式
如果移动端访问不佳,请使用–>GitHub版 背景 设计师给的设计图完全依照 IOS 的标准来的,导致很多细节的控件都得自己重写,最近的设计图中有显示滚动条,Android 默认的滚动条样式(带 ...
- 【Netty源码分析】Netty服务端bind端口过程
这一篇博客我们介绍一下Netty服务端绑定端口的过程,我们通过跟踪代码一直到NIO原生绑定端口的操作. 绑定端口操作 ChannelFuture future = serverBootstrap.bi ...
- 【移动开发】SharedPreferences的兼容版本
public class SharedPreferencesCompat { private static final String TAG = SharedPreferencesCompat.cla ...
- Servlet之异常处理
当一个 Servlet 抛出一个异常时,Web 容器在使用了exception-type 元素的 web.xml 中搜索与抛出异常类型相匹配的配置. 前提是必须在 web.xml 中使用 error- ...
- 利用Camera和Matrix实现有趣的卡片效果
这篇文章主要讲解一个翻转切换内容的卡片效果,主要利用Camera和Matrix来实现,主要是为了加深对Camera和Matrix的理解,如果对Camera和Matrix不清楚地童鞋可以看我的上篇文章: ...
- .so的封装调用
.so的创建和调用有一个特点,我们要知道.so的调用并不一定必须在Activity中进行,那么制作时也并不一定要在Activity中,但是,一旦.so制作成功,那么再调用时,调用的java类就必须跟制 ...
- Android动画深入分析
动画分类 Android动画可以分3种:View动画,帧动画和属性动画:属性动画为API11的新特性,在低版本是无法直接使用属性动画的,但可以用nineoldAndroids来实现(但是本质还是vii ...
- UNIX环境高级编程——线程同步之读写锁以及属性
读写锁和互斥量(互斥锁)很类似,是另一种线程同步机制,但不属于POSIX标准,可以用来同步同一进程中的各个线程.当然如果一个读写锁存放在多个进程共享的某个内存区中,那么还可以用来进行进程间的同步, 互 ...
- 分布式进阶(五)之JSVC配置
应用场景:在linux系统上进行项目开发,在部署java项目时,常用方法就是写一个shell脚本,但当服务器重启了,经常会忘了启动shell脚本了.所以我们需要把自己的应用变成linux的服务,当服务 ...