设计模式_代理模式_在SqlSessionTemplate(Spring)中的应用

本文深入解析SqlSessionTemplate的工作原理,包括其构造函数如何利用动态代理创建SqlSession,以及通过代理对象执行CRUD操作的机制。同时,文章阐述了SqlSessionTemplate如何自动管理SqlSession的生命周期,避免了手动关闭的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.SqlSessionTemplate的构造函数,根据传入的SqlSessionFactory和ExecutorType创建一个Spring管理的SqlSession,并生成SqlSession的动态代理对象
 1 public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,
 2       PersistenceExceptionTranslator exceptionTranslator) {
 3 
 4     notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required");
 5     notNull(executorType, "Property 'executorType' is required");
 6 
 7     this.sqlSessionFactory = sqlSessionFactory;
 8     this.executorType = executorType;
 9     this.exceptionTranslator = exceptionTranslator;
10     //这里使用了jdk的动态代理,为SqlSession创建了代理对象
11     this.sqlSessionProxy = (SqlSession) newProxyInstance(
12         SqlSessionFactory.class.getClassLoader(),
13         new Class[] { SqlSession.class },
14         new SqlSessionInterceptor());
15 }
 
2.创建一个名为SqlSessionInterceptor的InvocationHandler实现类,当调用SqlSession的代理对象的方法时,会调用这个 InvocationHandler实现类的invokd方法,这里,SqlSessionInterceptor中实现了对SqlSession的释放
 1 private class SqlSessionInterceptor implements InvocationHandler {
 2     @Override
 3     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 4       SqlSession sqlSession = getSqlSession(
 5           SqlSessionTemplate.this.sqlSessionFactory,
 6           SqlSessionTemplate.this.executorType,
 7           SqlSessionTemplate.this.exceptionTranslator);
 8       try {
 9         Object result = method.invoke(sqlSession, args);
10         if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
11           // force commit even on non-dirty sessions because some databases require
12           // a commit/rollback before calling close()
13           sqlSession.commit(true);
14         }
15         return result;
16       } catch (Throwable t) {
17         Throwable unwrapped = unwrapThrowable(t);
18         if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
19           // release the connection to avoid a deadlock if the translator is no loaded. See issue #22
20          //如果遇到异常,释放SqlSession
21           closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
22           sqlSession = null;
23           Throwable translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException) unwrapped);
24           if (translated != null) {
25             unwrapped = translated;
26           }
27         }
28         throw unwrapped;
29       } finally {
30         //最后,如果SqlSession不为空,释放SqlSesssion
31         if (sqlSession != null) {
32           closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
33         }
34       }
35     }
36   }

 

3.通过SqlSession的代理对象来执行相关的增删改查方法
 1 @Override
 2   public int insert(String statement) {
 3     //通过SqlSessionTemplate构造函数中生成的SqlSession的动态代理对象来执行 insert 操作
 4     return this.sqlSessionProxy.insert(statement);
 5 }
 6 
 7 @Override
 8   public int delete(String statement) {
 9     //通过SqlSessionTemplate构造函数中生成的SqlSession的动态代理对象来执行 delete 操作
10     return this.sqlSessionProxy.delete(statement);
11 }
12 
13 @Override
14   public int update(String statement) {
15     //通过SqlSessionTemplate构造函数中生成的SqlSession的动态代理对象来执行 update 操作
16     return this.sqlSessionProxy.update(statement);
17 }
18 
19 @Override
20   public <T> T selectOne(String statement, Object parameter) {
21     //通过SqlSessionTemplate构造函数中生成的SqlSession的动态代理对象来执行 selectOne 操作
22     return this.sqlSessionProxy.<T> selectOne(statement, parameter);
23 }

 

4.由于SqlSessionTemplate通过代理的方式帮我们维护了SqlSession的生命周期(close,rollback,comit这些),所以我们不能显示的调用close方法

1 @Override
2   public void close() {
3     //不可以对Spring管理的SqlSession执行close方法
4     throw new UnsupportedOperationException("Manual close is not allowed over a Spring managed SqlSession");
5 }

 

5.在SpringBoot项目中实测SqlSessionTemplate的方法执行,执行完方法后,会释放相应的SqlSession资源

 

转载于:https://www.cnblogs.com/rocker-pg/p/9699633.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值