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,方便操作关系型数据库的,封装了对数据库操作的过程,同时提供对象与数据之间的映射功能,解放了开发人员对访 ...
随机推荐
- wget 常用参数释义
wget 大法好啊,废话不多说,下面开始wget之旅吧. 下载限速 wget命令有一个内建的选项可以先顶下载任务占有的最大的带宽,从而保证其他应用程序的流畅运行. 具体使用--limit-rate 数 ...
- JAVA面向对象-----面向对象(基础预备知识汇总)
终于整理好了面向对象基础预备知识,但是有点多,所以你们懂的,贴图,较长的代码我还是会排版出来的,我不想把时间浪费在排版上在word里排版一次已经很浪费时间了,所以请谅解. public class C ...
- CSDN发表文章后老是待审核的原因
最近开始在csdn上写文章,发现老是文章被 待审核 ,于是便在网上搜集了下网友们的反馈,最后做出以下的整理. 1.CSDN检测到文章中的链接大于5,就会将文章列为"待审核",这个其 ...
- Hive-RCFile文件存储格式
在新建Hive表时,可以使用stored as rcfile来指定hive文件的存储方式为RCFile. 一.RCFile文件结构 下图是一个RCFile的文件结构形式. 从上图可以看出: 1)一张表 ...
- 在Linux环境下实现一个非常好的bash脚本框架
为了方便我日常工作中的编译环境,免去我敲命令行所浪费的时间,我个人写了一个非常有用而又简单的脚本框架,该框架即可以完成的工程源码编译,也可以清除,拷贝等等操作,具体需要开发者自己来实现细节,我的框架思 ...
- ROS讲座 关于ROS2和Gazebo C++ in Open Source Robotics
分享一个不错的介绍ROS2和Gazebo的视频讲座. Gazebo中的云彩飘动起来了!!!! 超清视频分享网址: http://v.youku.com/v_show/id_XMTcyMzY0Nz ...
- 1089. Insert or Merge (25)
题目如下: According to Wikipedia: Insertion sort iterates, consuming one input element each repetition, ...
- Transform介绍(Unity3D开发之二)
猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=491 可能unity中接触较早的 ...
- shell入门之流程控制语句
1.case 脚本: #!/bin/bash #a test about case case $1 in "lenve") echo "input lenve" ...
- 步步为营---- MuleEsb学习(一) 扫盲篇
本篇文章是基于不断的接触GXPT之后,对其技术开始不断的积累学习^^^,有很多问题带给我了思考,对于如何的处理各个部分的流程?这个如何处理?太多的问题促使着我一步一步的学习,在师哥们的指导下,逐步的清 ...