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,方便操作关系型数据库的,封装了对数据库操作的过程,同时提供对象与数据之间的映射功能,解放了开发人员对访 ...
随机推荐
- Dynamics CRM2016 新功能之从CRM APP中导出数据至EXCEL
新版的CRM对移动端做了很多的改进,这归咎于微软对APP端的越来越重视.自己装了个IOS版的APP,体验了下基本的功能,比原来好用很多很顺滑,这里要介绍的是一个新的数据导出功能. 咱们进入case列表 ...
- 两个activity或者activity和fragment传值
使用Fragment的时候可能需要在两个Fragment之间进行参数的传递,开始想着可以使用SharedPreferences进行处理,想想这些简单的参数没有必要使用这么麻烦的方式去实现,翻了一下Fr ...
- UNIX网络编程——进程间通信概述
一.顺序程序与并发程序特征 顺序程序特征 顺序性封闭性:(运行环境的封闭性)确定性可再现性 并发程序特征 共享性并发性随机性 二.进程互斥 1.由于各进程要求共享资源,而且有些资源需要互斥使用,因此各 ...
- Android项目开发填坑记-Fragment的onAttach
背景 现在Android开发多使用一个Activity管理多个Fragment进行开发,不免需要两者相互传递数据,一般是给Fragment添加回调接口,让Activity继承并实现. 回调接口一般都写 ...
- Android简易实战教程--第十七话《自定义彩色环形进度条》
转载请注明出处:http://blog.csdn.net/qq_32059827/article/details/52203533 点击打开链接 在Android初级教程里面,介绍了shape用法 ...
- Android 自定义View-android学习之旅(十四)
自定义View的步骤 当andoid提供的系统组件不满足要求时候,完全可以集成View来派生自定义组件. 首定定义一个继承View的子类,然后重写他一个或几个方法. 重写的方法介绍 构造器:这是定制V ...
- XCode5添加新建类模板(Cocos2dx Template Class for Scene or Layer)
猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=505 因为常用cocos2dx开 ...
- shell入门之流程控制语句
1.case 脚本: #!/bin/bash #a test about case case $1 in "lenve") echo "input lenve" ...
- java实现异步调用实例
在JAVA平台,实现异步调用的角色有如下三个角色: 调用者 取货凭证 真实数据 一个调用者在调用耗时操作,不能立即返回数据时,先返回一个取货凭证.然后在过一断时间后凭取货凭证来获取真正的数据. ...
- Android面试题总结
1.Android dvm的进程和Linux的进程, 应用程序的进程是否为同一个概念 DVM指dalivk的虚拟机.每一个Android应用程序都在它自己的进程中运行,都拥有一个独立的Dalvik虚拟 ...