200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > Mybatis源码学习(三)SqlSession详解

Mybatis源码学习(三)SqlSession详解

时间:2023-08-10 13:35:45

相关推荐

Mybatis源码学习(三)SqlSession详解

前言

上一章节我们学习了SqlSessionFactory的源码,SqlSessionFactory中的方法都是围绕着SqlSession来的.,那么SqlSession又是什么东东呢?这一章节我们就来揭开它的真面目吧!

1. SqlSession源码详解

SqlSession是一个接口类,文档上注明它是mybatis的一个主要的java 接口.官方都说很重要了,那肯定是非常重要.它的主要功能是执行命令,获取mapper和管理事务.

SqlSession有两个实现类,分别是DefaultSqlSessionSqlSessionManager,上一章节也出现过SqlSessionManager,大家还记得吗?SqlSessionManager既实现了SqlSession也实现了SqlSessionFactory.话不多说,详细学习以下两个类的源码吧!

2. DefaultSqlSession源码详解

2.1DefaultSqlSession源码

public class DefaultSqlSession implements SqlSession {/*** 全局配置对象*/private final Configuration configuration;/*** sql执行器*/private final Executor executor;/*** 是否自动提交*/private final boolean autoCommit;/*** 是否脏数据*/private boolean dirty;/*** 游标列表*/private List<Cursor<?>> cursorList;/**构造函数* @param configuration 核心配置对象* @param executor sql执行器* @param autoCommit 是否自动提交*/public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {this.configuration = configuration;this.executor = executor;this.dirty = false;this.autoCommit = autoCommit;}/**构造函数* @param configuration 核心配置对象* @param executor sql执行器*/public DefaultSqlSession(Configuration configuration, Executor executor) {this(configuration, executor, false);}/**查询单条数据并返回对象* @param statement the statement* @param <T> 返回对象类型* @return 对象*/@Overridepublic <T> T selectOne(String statement) {return this.selectOne(statement, null);}/**查询单条数据并返回对象* @param statement the statement* @param parameter sql语句参数* @param <T> 返回对象类型* @return 对象*/@Overridepublic <T> T selectOne(String statement, Object parameter) {// Popular vote was to return null on 0 results and throw exception on too many.//调用selectListList<T> list = this.selectList(statement, parameter);if (list.size() == 1) {//结果为1条数据时,返回第0条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 {//返回nullreturn null;}}/**map查询* @param statement Unique identifier matching the statement to use.* @param mapKey The property to use as key for each value in the list.* @param <K> 返回的map的key的泛型* @param <V> 返回的map的值的泛型* @return返回map<K,V>*/@Overridepublic <K, V> Map<K, V> selectMap(String statement, String mapKey) {//调用selectMapreturn this.selectMap(statement, null, mapKey, RowBounds.DEFAULT);}/**map查询* @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 <K> 返回的map的key的泛型* @param <V> 返回的map的值的泛型* @return返回map<K,V>*/@Overridepublic <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey) {//调用selectMapreturn this.selectMap(statement, parameter, mapKey, RowBounds.DEFAULT);}/**map查询* @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* @param <K> 返回的map的key的泛型* @param <V> 返回的map的值的泛型* @return返回map<K,V>*/@Overridepublic <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) {//调用selectList获取结果final List<? extends V> list = selectList(statement, parameter, rowBounds);//初始化一个默认的Map结果处理器final DefaultMapResultHandler<K, V> mapResultHandler = new DefaultMapResultHandler<>(mapKey,configuration.getObjectFactory(), configuration.getObjectWrapperFactory(), configuration.getReflectorFactory());//初始化一个默认的结果上下文对象final DefaultResultContext<V> context = new DefaultResultContext<>();for (V o : list) {//遍历结果列表,放入context中context.nextResultObject(o);//使用Map结果处理器处理上下文mapResultHandler.handleResult(context);}//从结果处理器中获取处理完的map<K,V>返回return mapResultHandler.getMappedResults();}/**游标查询* @param statement Unique identifier matching the statement to use.* @param <T> 返回对象类型* @return对象*/@Overridepublic <T> Cursor<T> selectCursor(String statement) {return selectCursor(statement, null);}/**游标查询* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @param <T> 返回对象类型* @return对象*/@Overridepublic <T> Cursor<T> selectCursor(String statement, Object parameter) {return selectCursor(statement, parameter, RowBounds.DEFAULT);}/**游标查询* @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* @param <T> 返回对象类型* @return对象*/@Overridepublic <T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds) {try {//使用全局配置对象中的mappedStatements获取MappedStatement对象MappedStatement ms = configuration.getMappedStatement(statement);//调用sql处理器查询Cursor<T> cursor = executor.queryCursor(ms, wrapCollection(parameter), rowBounds);//把游标注册到游标列表中,方便后续统一管理游标registerCursor(cursor);return cursor;} catch (Exception e) {throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);} finally {ErrorContext.instance().reset();}}/**查询列表* @param statement Unique identifier matching the statement to use.* @param <E> 结果的泛型* @return结果列表*/@Overridepublic <E> List<E> selectList(String statement) {return this.selectList(statement, null);}/**查询列表* @param statement Unique identifier matching the statement to use.* @param parameter A parameter object to pass to the statement.* @param <E> 结果的泛型* @return结果列表*/@Overridepublic <E> List<E> selectList(String statement, Object parameter) {//调用selectListreturn this.selectList(statement, parameter, RowBounds.DEFAULT);}/**查询列表* @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* @param <E> 结果的泛型* @return结果列表*/@Overridepublic <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {try {//使用全局配置对象中的mappedStatements获取MappedStatement对象MappedStatement ms = configuration.getMappedStatement(statement);//调用sql处理器查询return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);} catch (Exception e) {throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);} finally {ErrorContext.instance().reset();}}/**带结果处理器的查询* @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*/@Overridepublic void select(String statement, Object parameter, ResultHandler handler) {//调用selectselect(statement, parameter, RowBounds.DEFAULT, handler);}/**带结果处理器的查询* @param statement Unique identifier matching the statement to use.* @param handler ResultHandler that will handle each retrieved row*/@Overridepublic void select(String statement, ResultHandler handler) {select(statement, null, RowBounds.DEFAULT, handler);}/**带结果处理器的查询* @param statement Unique identifier matching the statement to use.* @param parameter the parameter* @param rowBounds RowBound instance to limit the query results* @param handler*/@Overridepublic void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {try {//使用全局配置对象中的mappedStatements获取MappedStatement对象MappedStatement ms = configuration.getMappedStatement(statement);//调用sql处理器查询executor.query(ms, wrapCollection(parameter), rowBounds, handler);} catch (Exception e) {throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);} finally {ErrorContext.instance().reset();}}/**插入数据* @param statement Unique identifier matching the statement to execute.* @return影响的行数*/@Overridepublic int insert(String statement) {//调用insertreturn insert(statement, null);}/**插入数据* @param statement Unique identifier matching the statement to execute.* @param parameter A parameter object to pass to the statement.* @return影响的行数*/@Overridepublic int insert(String statement, Object parameter) {//调用updatereturn update(statement, parameter);}/**更新数据* @param statement Unique identifier matching the statement to execute.* @return影响的行数*/@Overridepublic int update(String statement) {//调用updatereturn update(statement, null);}/**更新数据* @param statement Unique identifier matching the statement to execute.* @param parameter A parameter object to pass to the statement.* @return影响的行数*/@Overridepublic int update(String statement, Object parameter) {try {//设置脏数据状态为truedirty = true;//使用全局配置对象中的mappedStatements获取MappedStatement对象MappedStatement ms = configuration.getMappedStatement(statement);//调用sql处理器更新return executor.update(ms, wrapCollection(parameter));} catch (Exception e) {throw ExceptionFactory.wrapException("Error updating database. Cause: " + e, e);} finally {ErrorContext.instance().reset();}}/**删除数据* @param statement Unique identifier matching the statement to execute.* @return影响的行数*/@Overridepublic int delete(String statement) {//调用updatereturn update(statement, null);}/**删除数据* @param statement Unique identifier matching the statement to execute.* @param parameter A parameter object to pass to the statement.* @return影响的行数*/@Overridepublic int delete(String statement, Object parameter) {//调用更新return update(statement, parameter);}/*** 提交事务*/@Overridepublic void commit() {commit(false);}/**提交事务* @param force是否强制提交*/@Overridepublic void commit(boolean force) {try {//调用执行器提交事务mit(isCommitOrRollbackRequired(force));//设置脏数据状态为falsedirty = false;} catch (Exception e) {throw ExceptionFactory.wrapException("Error committing transaction. Cause: " + e, e);} finally {ErrorContext.instance().reset();}}/*** 回滚事务*/@Overridepublic void rollback() {rollback(false);}/**回滚事务* @param force forces connection rollback*/@Overridepublic void rollback(boolean force) {try {//调用执行器回滚事务executor.rollback(isCommitOrRollbackRequired(force));//设置脏数据状态为falsedirty = false;} catch (Exception e) {throw ExceptionFactory.wrapException("Error rolling back transaction. Cause: " + e, e);} finally {ErrorContext.instance().reset();}}/**批量处理* @return 返回批量处理的结果*/@Overridepublic List<BatchResult> flushStatements() {try {//调用执行器进行批量操作return executor.flushStatements();} catch (Exception e) {throw ExceptionFactory.wrapException("Error flushing statements. Cause: " + e, e);} finally {ErrorContext.instance().reset();}}/*** 关闭sqlsession*/@Overridepublic void close() {try {//调用执行器进行关闭executor.close(isCommitOrRollbackRequired(false));//关闭所有游标closeCursors();//设置脏数据状态为falsedirty = false;} finally {ErrorContext.instance().reset();}}/*** 关闭全部游标*/private void closeCursors() {if (cursorList != null && !cursorList.isEmpty()) {for (Cursor<?> cursor : cursorList) {//遍历游标列表,进行关闭操作try {cursor.close();} catch (IOException e) {throw ExceptionFactory.wrapException("Error closing cursor. Cause: " + e, e);}}//清空游标cursorList.clear();}}/**获取全局配置对象* @return 全局配置对象*/@Overridepublic Configuration getConfiguration() {return configuration;}/**获取Mapper<T>的动态代理类* @param type Mapper interface class* @param <T> 返回对象的泛型* @returnMapper接口的动态代理类*/@Overridepublic <T> T getMapper(Class<T> type) {//从核心配置对象中获取mapper, 实际是从mapperRegistry中获取mapper接口的代理工厂,使用代理工厂创建的动态代理类return configuration.getMapper(type, this);}/**获取数据库连接* @return数据库连接*/@Overridepublic Connection getConnection() {try {//调用执行器获取连接return executor.getTransaction().getConnection();} catch (SQLException e) {throw ExceptionFactory.wrapException("Error getting a new connection. Cause: " + e, e);}}/*** 清除缓存*/@Overridepublic void clearCache() {//调用执行器清除本地缓存executor.clearLocalCache();}/**注册游标* @param cursor游标对象* @param <T> 泛型*/private <T> void registerCursor(Cursor<T> cursor) {if (cursorList == null) {cursorList = new ArrayList<>();}//把游标加入到cursorListcursorList.add(cursor);}/**判断是否需求提交或者回滚* @param force 是否强制提交或回滚* @return 是否需求提交或者回滚*/private boolean isCommitOrRollbackRequired(boolean force) {//如果不是自动提交并且有脏数据返回true//如果强制提交或回滚返回truereturn (!autoCommit && dirty) || force;}/**将Collection或者数组类型的参数转换成Map* @param object参数对象* @return 包装后的对象*/private Object wrapCollection(final Object object) {return ParamNameResolver.wrapToMapIfCollection(object, null);}/*** @deprecated Since 3.5.5*/@Deprecatedpublic static class StrictMap<V> extends HashMap<String, V> {private static final long serialVersionUID = -5741767162221585340L;@Overridepublic V get(Object key) {if (!super.containsKey(key)) {throw new BindingException("Parameter '" + key + "' not found. Available parameters are " + this.keySet());}return super.get(key);}}}

DefaultSqlSession的方法分类

1.selectOne(),selectMap(),selectList()为一类,它们的实现都是通过selectList()得到的结构进行处理的

2.selectCursor()

3.select()

4.insert(),update(),delete()为一类,它们的实现都是通过update()

5.实现的事务相关的和其他方法

2.2 configuration.getMappedStatement(statement)

configuration的内部是维护了一个Map<String, MappedStatement> mappedStatements

在获取之前如果还有未完成的Statements,会先执行buildAllStatements()

public MappedStatement getMappedStatement(String id, boolean validateIncompleteStatements) {if (validateIncompleteStatements) {buildAllStatements();}return mappedStatements.get(id);}

那这个Map是什么时候插入值的呢,我们进行代码的跟踪,有没有很眼熟,是上一章的最后一节我们说到的解析所有的Mapper配置

在解析的过程里,会把MappedStatement的id属性作为key,MappedStatement作为值放入到mappedStatements中

ps: 查看调用关系快捷键 Ctrl + Alt + H

2.3 Executor

我们通过调用栈来看下Executor到底是什么时候进行初始化的呢

private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {Transaction tx = null;try {final Environment environment = configuration.getEnvironment();final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);//通过configuration创建一个Executorfinal Executor executor = configuration.newExecutor(tx, execType);return new DefaultSqlSession(configuration, executor, autoCommit);} catch (Exception e) {closeTransaction(tx); // may have fetched a connection so lets call close()throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);} finally {ErrorContext.instance().reset();}}private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {try {boolean autoCommit;try {autoCommit = connection.getAutoCommit();} catch (SQLException e) {// Failover to true, as most poor drivers// or databases won't support transactionsautoCommit = true;}final Environment environment = configuration.getEnvironment();final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);final Transaction tx = transactionFactory.newTransaction(connection);//通过configuration创建一个Executorfinal Executor executor = configuration.newExecutor(tx, execType);return new DefaultSqlSession(configuration, executor, autoCommit);} catch (Exception e) {throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);} finally {ErrorContext.instance().reset();}}

public Executor newExecutor(Transaction transaction, ExecutorType executorType)代码

public Executor newExecutor(Transaction transaction, ExecutorType executorType) {//为空返回默认的executorType ExecutorType.SIMPLEexecutorType = executorType == null ? defaultExecutorType : executorType;executorType = executorType == null ? ExecutorType.SIMPLE : executorType;Executor executor;//根据不同类型返回不同的Executor if (ExecutorType.BATCH == executorType) {//批处理型executor = new BatchExecutor(this, transaction);} else if (ExecutorType.REUSE == executorType) {//复用型executor = new ReuseExecutor(this, transaction);} else {//简单型executor = new SimpleExecutor(this, transaction);}//如果开启缓存,用缓存执行器对原始执行器进行包装,返回一个带缓存功能的执行器//默认是开启缓存的if (cacheEnabled) {executor = new CachingExecutor(executor);}//为所有的执行链加入当前的执行器插件executor = (Executor) interceptorChain.pluginAll(executor);return executor;}

interceptorChain.pluginAll(executor)

public Object pluginAll(Object target) {for (Interceptor interceptor : interceptors) {target = interceptor.plugin(target);}return target;}

interceptor.plugin(target)

default Object plugin(Object target) {return Plugin.wrap(target, this);}

Plugin.wrap(target, this)

public static Object wrap(Object target, Interceptor interceptor) {//获取当前的interceptor上的注解中定义的Signature[],把需要代理的类和方法放入Map中Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);Class<?> type = target.getClass();//匹配当前类有没有需要被代理的接口,有则返回代理对象,无返回原对象Class<?>[] interfaces = getAllInterfaces(type, signatureMap);if (interfaces.length > 0) {return Proxy.newProxyInstance(type.getClassLoader(),interfaces,new Plugin(target, interceptor, signatureMap));}return target;}

MyInterceptor和PageInterceptor类上的@Intercepts注解

此处定义的都是对Executor类的下面两个方法进行代理

query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql)

query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler)

最后代理两次后返回的Executor类

3. SqlSessionManager源码详解

3.1 私有的构造方法

//内部的SqlSessionFactory,为实现SqlSessionFactory相关接口而使用private final SqlSessionFactory sqlSessionFactory;//内部的SqlSession代理类,为实现SqlSession相关接口而使用private final SqlSession sqlSessionProxy;//ThreadLocal<SqlSession> 事务相关等方法操作是使用private final ThreadLocal<SqlSession> localSqlSession = new ThreadLocal<>();//私有构造函数private SqlSessionManager(SqlSessionFactory sqlSessionFactory) {this.sqlSessionFactory = sqlSessionFactory;this.sqlSessionProxy = (SqlSession) Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(),new Class[]{SqlSession.class},new SqlSessionInterceptor());}

3.2 SqlSession的代理类SqlSessionInterceptor

private class SqlSessionInterceptor implements InvocationHandler {public SqlSessionInterceptor() {// Prevent Synthetic Access}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//从LocalThread中获取SqlSessionfinal SqlSession sqlSession = SqlSessionManager.this.localSqlSession.get();if (sqlSession != null) {//LocalThread中有SqlSession,则使用try {return method.invoke(sqlSession, args);} catch (Throwable t) {throw ExceptionUtil.unwrapThrowable(t);}} else {//LocalThread中无SqlSession,获取一个SqlSessiontry (SqlSession autoSqlSession = openSession()) {try {final Object result = method.invoke(autoSqlSession, args);//手动提交mit();return result;} catch (Throwable t) {//手动回滚autoSqlSession.rollback();throw ExceptionUtil.unwrapThrowable(t);}}}}}

3.3 其他事务等方法

以下方法都是通过LocalThread中的SqlSession进行操作的

@Overridepublic void clearCache() {final SqlSession sqlSession = localSqlSession.get();if (sqlSession == null) {throw new SqlSessionException("Error: Cannot clear the cache. No managed session is started.");}sqlSession.clearCache();}@Overridepublic void commit() {final SqlSession sqlSession = localSqlSession.get();if (sqlSession == null) {throw new SqlSessionException("Error: Cannot commit. No managed session is started.");}mit();}@Overridepublic void commit(boolean force) {final SqlSession sqlSession = localSqlSession.get();if (sqlSession == null) {throw new SqlSessionException("Error: Cannot commit. No managed session is started.");}mit(force);}@Overridepublic void rollback() {final SqlSession sqlSession = localSqlSession.get();if (sqlSession == null) {throw new SqlSessionException("Error: Cannot rollback. No managed session is started.");}sqlSession.rollback();}@Overridepublic void rollback(boolean force) {final SqlSession sqlSession = localSqlSession.get();if (sqlSession == null) {throw new SqlSessionException("Error: Cannot rollback. No managed session is started.");}sqlSession.rollback(force);}@Overridepublic List<BatchResult> flushStatements() {final SqlSession sqlSession = localSqlSession.get();if (sqlSession == null) {throw new SqlSessionException("Error: Cannot rollback. No managed session is started.");}return sqlSession.flushStatements();}@Overridepublic void close() {final SqlSession sqlSession = localSqlSession.get();if (sqlSession == null) {throw new SqlSessionException("Error: Cannot close. No managed session is started.");}try {sqlSession.close();} finally {localSqlSession.set(null);}}

总结

SqlSession的两个实现类DefaultSqlSessionSqlSessionManager.SqlSessionManager是通过DefaultSqlSession实现功能的.而DefaultSqlSession是通过内部的Executor实现的.后续章节我们再对Executor相关的代码进行详细的学习

喜欢的小伙伴请动动小手关注和点赞吧,也可留言一起探讨怎样更好的学习源码!!!

文章链接

Mybatis源码学习(一)初探执行流程

Mybatis源码学习(二)配置文件解析到SqlSessionFactory构建

Mybatis源码学习(三)SqlSession详解

Mybatis源码学习(四)自定义Mapper方法执行流程

Mybatis源码学习(五)Executor和StatementHandler详解

Mybatis源码学习(六)结果集自动封装机制

Mybatis源码学习(七)mybatis缓存详解

Mybatis源码学习(八)Mybatis设计模式总结

学习资料整理

本人作为Java开发菜鸡,平时也收集了很多学习视频,在此分享给大家一起学习

整套VIP学习视频

架构师相关视频

扫码领取

更多资料链接

Java免费学习视频下载

Python免费学习视频下载

Web前端免费学习视频下载

人工智能免费学习视频下载

大数据免费学习视频下载

UI设计免费学习视频下载

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。