三种 SqlSession

三种 SqlSession

SqlSession​ 是一个接口,并且里面包含了许多 CRUD 操作数据库等方法。

SqlSession​​ 它有三个实现类,分别是 SqlSessionManager​​ 、DefaultSqlSession​​ 和 SqlSessionTemplate​​,其中 DefaultSqlSession​​ 它的默认实现类。

DefaultSqlSession 是线程不安全的 Sqlsession 。也就是说 DefaultSqlSession 不能是单例,必须是多例的。

SqlSessionManager​ 和 SqlSessionTemplate​ 是 SqlSession 的代理版,每次新建一个代理对象。姿势都是一样的,但是代理逻辑SqlSessionInterceptor 是不一样的。

代理 DefaultSqlSession 实现复用

在执行 getSqlSession 时,两则都是利用 SessionFactory 工厂创建一个 DefaultSqlSession。然后尽可能复用 DefaultSqlSession,而非多例的每次使用都创建一个 DefaultSqlSession。

java 复制代码
SqlSession session = sessionFactory.openSession(executorType);

不同之处在于复用逻辑,先看 SqlSessionTemplate 的:

  1. SqlSessionTemplate 会将 SqlSession 封装成 SqlSessionHolder,并有利用引用计数法,当 referenceCount>0。表示 SqlSession 还在使用。
  2. 将 sqlSessionHolder 存放到 TransactionSynchronizationManagersynchronizations 中。synchronizations 是一个 set 集合。

相对 SqlSessionTemplate 的,SqlSessionManage 的比较简单一点。

  1. SqlSessionManage 内部有一个线程私有变量 localSqlSession。private final ThreadLocal<SqlSession> localSqlSession = new ThreadLocal();
  2. SqlSessionManage 会将 DefaultSqlSession 放入到 ThreadLocal 线程私有的变量 localSqlSession 中
  3. 用的时候先从 localSqlSession 中获取 DefaultSqlSession,如果没有获取到则创建。
SqlSessionManager 的代理逻辑
java 复制代码
private SqlSessionManager(){
    this.sqlSessionProxy = (SqlSession)Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(),
    new Class[]{SqlSession.class}, new SqlSessionInterceptor());
}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    SqlSession sqlSession = (SqlSession)SqlSessionManager.this.localSqlSession.get();
    if (sqlSession != null) {
       return method.invoke(sqlSession, args);
    } else {
        SqlSession autoSqlSession = SqlSessionManager.this.openSession();
        Object var8;
        try {
            try {
                Object result = method.invoke(autoSqlSession, args);
                autoSqlSession.commit();
                var8 = result;
            } catch (Throwable var20) {
                autoSqlSession.rollback();
                throw ExceptionUtil.unwrapThrowable(var20);
            }
        } catch (Throwable var21) {

        } finally {
            if (autoSqlSession != null) {
                autoSqlSession.close(); 
            }
        }

        return var8;
    }
}
SqlSessionTemplate 的代理逻辑
java 复制代码
private SqlSessionTemplate(){
    this.sqlSessionProxy = (SqlSession)Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(), 
    new Class[]{SqlSession.class}, new SqlSessionInterceptor());
}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    SqlSession sqlSession = SqlSessionUtils.getSqlSession(SqlSessionTemplate.this.sqlSessionFactory, 
                SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);

    Object unwrapped;
    try {
        Object result = method.invoke(sqlSession, args);
        if (!SqlSessionUtils.isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
            sqlSession.commit(true);
        }

        unwrapped = result;
    } catch (Throwable var11) {
        unwrapped = ExceptionUtil.unwrapThrowable(var11);
        if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
            SqlSessionUtils.closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
            sqlSession = null;
            Throwable translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException)unwrapped);
            if (translated != null) {
                unwrapped = translated;
            }
        }

        throw (Throwable)unwrapped;
    } finally {
        if (sqlSession != null) {
            SqlSessionUtils.closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
        }

    }

    return unwrapped;
}

相关推荐
aloha_7898 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
毕业设计制作和分享8 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
paopaokaka_luck12 小时前
基于Spring Boot+Vue的助农销售平台(协同过滤算法、限流算法、支付宝沙盒支付、实时聊天、图形化分析)
java·spring boot·小程序·毕业设计·mybatis·1024程序员节
cooldream200912 小时前
Spring Boot中集成MyBatis操作数据库详细教程
java·数据库·spring boot·mybatis
不像程序员的程序媛13 小时前
mybatisgenerator生成mapper时报错
maven·mybatis
小布布的不16 小时前
MyBatis 返回 Map 或 List<Map>时,时间类型数据,默认为LocalDateTime,响应给前端默认含有‘T‘字符
前端·mybatis·springboot
背水18 小时前
Mybatis基于注解的关系查询
mybatis
free_girl_fang18 小时前
高效作业之Mybatis缓存
java·ide·缓存·mybatis
十二同学啊1 天前
Mybatis拦截器中获取@RequestBody表单的值修改查询SQL
数据库·sql·mybatis
毕业设计制作和分享1 天前
ssm好例文共享平台的设计与实现+jsp
java·开发语言·vue.js·spring boot·毕业设计·mybatis