?SqlSession
? 是一个接口,并且里面包含了许多 CRUD 操作数据库等方法。
?SqlSession
?? 它有三个实现类,分别是 SqlSessionManager
?? 、DefaultSqlSession
?? 和 SqlSessionTemplate
??,其中 DefaultSqlSession
?? 它的默认实现类。
DefaultSqlSession 是线程不安全的 Sqlsession 。也就是说 DefaultSqlSession 不能是单例,必须是多例的。
?SqlSessionManager
? 和 SqlSessionTemplate
? 是 SqlSession 的代理版,每次新建一个代理对象。姿势都是一样的,但是代理逻辑SqlSessionInterceptor 是不一样的。
在执行 getSqlSession 时,两则都是利用 SessionFactory 工厂创建一个 DefaultSqlSession。然后尽可能复用 DefaultSqlSession,而非多例的每次使用都创建一个 DefaultSqlSession。
SqlSession session = sessionFactory.openSession(executorType);
不同之处在于复用逻辑,先看 SqlSessionTemplate 的:
SqlSessionTemplate
?会将 SqlSession 封装成 SqlSessionHolder,并有利用引用计数法,当 referenceCount>0。表示 SqlSession 还在使用。TransactionSynchronizationManager
?的 synchronizations
?中。synchronizations
?是一个 set 集合。相对 SqlSessionTemplate 的,SqlSessionManage 的比较简单一点。
private final ThreadLocal<SqlSession> localSqlSession = new ThreadLocal();
?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;
}
}
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;
}
?