Myabtis 源码解析九-简单介绍SqlsessionManager

本文介绍了MyBatis框架中SqlSessionManager的作用与实现原理,详细解释了它是如何通过对SqlSessionFactory进行封装来实现线程安全的自动新建和释放SqlSession。同时对比了SqlSessionManager与DefaultSqlSessionFactory的不同之处。

介绍

  1. 从下面的继承关系可以看出,SqlSeessionManage是对SqlSessionFactory, SqlSession的封装,或者是对SqlSessionFactory的封装
public class SqlSessionManager implements SqlSessionFactory, SqlSession 

从mybatis目前的提供官方文档来看,似乎该类已被弃用,其功能被DefaultSqlSession类和DefaultSqlSessionFactory类所代替

另外:SqlSessionManager是可以保证线程安全和自动新建和释放.

使用

创建

public static SqlSessionManager newInstance(SqlSessionFactory sqlSessionFactory) {
    return new SqlSessionManager(sqlSessionFactory);
  }

使用其创建SqlSession.

private static SqlSession sqlSession;
public static SqlSession getSqlSessionTest(){
    if(sqlSession == null){
      //构建使用的SqlSessionFactory
      SqlSessionFactory sqlSessionFactory = MyBatisUtil.getSqlSessionFactory();
      sqlSession = SqlSessionManager.newInstance(sqlSessionFactory);
    }
    return sqlSession;
}

线程安全分析

与DefaultSqlSessionFactory不同的是,SqlSessionManager提供了一个本地线程变量(ThreadLocal localSqlSession),每当通过startManagedSession()获得session实例的时候,会在本地线程保存session实例。这是其一不同。

SqlSessionManager.java
 public void startManagedSession() {
    this.localSqlSession.set(openSession());
  }

调用分析

SqlSessionManager.java

 private SqlSessionManager(SqlSessionFactory sqlSessionFactory) {
    this.sqlSessionFactory = sqlSessionFactory;
    这里创建sqlSession的代理类
    this.sqlSessionProxy = (SqlSession) Proxy.newProxyInstance(
        SqlSessionFactory.class.getClassLoader(),
        new Class[]{SqlSession.class},
        new SqlSessionInterceptor());
  }

 //sqlSession代理类
  private class SqlSessionInterceptor implements InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    //通过这个代理类,获取本线程的SqlSession
      final SqlSession sqlSession = SqlSessionManager.this.localSqlSession.get();
      if (sqlSession != null) {
        try {
          return method.invoke(sqlSession, args);
        } catch (Throwable t) {
          throw ExceptionUtil.unwrapThrowable(t);
        }
      } else {
        final SqlSession autoSqlSession = openSession();
        try {
          final Object result = method.invoke(autoSqlSession, args);
          autoSqlSession.commit();
          return result;
        } catch (Throwable t) {
          autoSqlSession.rollback();
          throw ExceptionUtil.unwrapThrowable(t);
        } finally {
          autoSqlSession.close();
        }
      }
    }

参考

Mybatis 通过SqlSessionManager SqlSessionFactory 构建线程安全的

mybatis源码分析(3)——SqlSessionManager类

单纯使用Mybatis框架 如何构建线程安全的SqlSession

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值