MyBatis创建SqlSession可以直接使用DefaultSqlSession 吗?
我們現(xiàn)在已經(jīng)有一個DefaultSqlSessionFactory,按照編程式的開發(fā)過程,我們接下來就會創(chuàng)建一個SqlSession 的實現(xiàn)類,但是在Spring 里面,我們不是直接使用DefaultSqlSession 的,而是對它進(jìn)行了一個封裝,這個SqlSession 的實現(xiàn)類就是SqlSessionTemplate。這個跟Spring 封裝其他的組件是一樣的,比如JdbcTemplate,RedisTemplate 等等,也是Spring 跟MyBatis 整合的最關(guān)鍵的一個類。
為什么不用DefaultSqlSession?它是線程不安全的,注意看類上的注解:
Note that this class is not Thread-Safe.而SqlSessionTemplate 是線程安全的。
* Thread safe, Spring managed, {@code SqlSession} that works with Spring回顧一下SqlSession 的生命周期:
| 對象 | 生命周期 |
| SqlSessionFactoryBuiler | 方法局部(method) |
| SqlSessionFactory(單例) | 應(yīng)用級別(application) |
| SqlSession | 請求和操作(request/method) |
| Mapper | 方法(method) |
在編程式的開發(fā)中,SqlSession 我們會在每次請求的時候創(chuàng)建一個,但是Spring里面只有一個SqlSessionTemplate(默認(rèn)是單例的),多個線程同時調(diào)用的時候怎么保證線程安全?
思考:為什么SqlSessionTemplate 是線程安全的?
思考:在編程式的開發(fā)中,有什么方法保證SqlSession 的線程安全?
SqlSessionTemplate 里面有DefaultSqlSession 的所有的方法:selectOne()、selectList()、insert()、update()、delete(),不過它都是通過一個代理對象實現(xiàn)的。這個代理對象在構(gòu)造方法里面通過一個代理類創(chuàng)建:
this.sqlSessionProxy = (SqlSession) newProxyInstance(SqlSessionFactory.class.getClassLoader(),new Class[] { SqlSession.class },new SqlSessionInterceptor());所有的方法都會先走到內(nèi)部代理類SqlSessionInterceptor 的invoke()方法:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {SqlSession sqlSession = getSqlSession(SqlSessionTemplate.this.sqlSessionFactory,SqlSessionTemplate.this.executorType,SqlSessionTemplate.this.exceptionTranslator);try {Object result = method.invoke(sqlSession, args);首先會使用工廠類、執(zhí)行器類型、異常解析器創(chuàng)建一個sqlSession,然后再調(diào)用sqlSession 的實現(xiàn)類,實際上就是在這里調(diào)用了DefaultSqlSession 的方法。
?
總結(jié)
以上是生活随笔為你收集整理的MyBatis创建SqlSession可以直接使用DefaultSqlSession 吗?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MyBatis关键配置-创建会话工厂
- 下一篇: MyBatis创建SqlSession-