
SqlSessionFactoryBuilder:build方法创建SqlSessionFactory实例。
SqlSessionFactory:创建SqlSession实例的工厂。
SqlSession:用于执行持久化 *** 作的对象,类似于jdbc中的Connection。
SqlSessionTemplate:MyBatis提供的持久层访问模板化的工具,线程安全,可通过构造参数或依赖注入SqlSessionFactory实例。
Hibernate是与MyBatis类似的orm框架,这里与Hibernate进行一下对比,Hibernate中对于connection的管理,是通过以下几个重要的类:
SessionFactory:创建Session实例的工厂,类似于MyBatis中的SqlSessionFactory。
Session:用来执行持久化 *** 作的对象,类似于jdbc中的Connection。
HibernateTemplate:Hibernate提供的持久层访问模板化的工具,线程安全,可通过构造参数或依赖注入SessionFactory实例。
在日常的开发中,我们经常需要这样对MyBatis和Spring进行集成,把sqlSessionFactory交给Spring管理,通常情况下,我们这样配置:
<code class="hljs nimrod"><bean id=<span class="hljs-string">"sqlSessionFactory" class=<span class="hljs-string">"org.mybatis.spring.SqlSessionFactoryBean">
<property name=<span class="hljs-string">"dataSource" <span class="hljs-keyword">ref=<span class="hljs-string">"dataSource" />
</bean></span></span></span></span></span></code>
通过上面的配置,Spring将自动创建一个SqlSessionFactory对象,其中使用到了org.mybatis.spring.SqlSessionFactoryBean,其 是MyBatis为Spring提供的用于创建SqlSessionFactory的类,将在Spring应用程序的上下文建议一下可共享的 MyBatis SqlSessionFactory实例,我们可以通过依赖注入将SqlSessionFactory传递给MyBatis的一些接口。
如果通过Spring进行事务的管理,我们需要增加Spring注解的事务管理机制,如下配置:
<code class="hljs nimrod"><bean id=<span class="hljs-string">"transactionManager" class=<span class="hljs-string">"org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name=<span class="hljs-string">"dataSource" <span class="hljs-keyword">ref=<span class="hljs-string">"dataSource" />
</bean>
<tx:annotation-driven/></span></span></span></span></span></code>
这样,我们就可以使用Spring @Transactional注解,进行事务的控制,表明所注释的方法应该在一个事务中运行。 Spring将在事务成功完成后提交事务,在事务发生错误时进行异常回滚,而且,Spring会将产生的MyBatis异常转换成适当的 DataAccessExceptions,从而提供具体的异常信息。
下面,我们通过分析SqlSessionUtils中getSession的源码,来详细的了解一下sqlSession的产生过程,源码如下:
<code class="hljs d"><span class="hljs-keyword">public <span class="hljs-keyword">static SqlSession getSqlSession(SqlSessionFactory sessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator) {
notNull(sessionFactory, <span class="hljs-string">"No SqlSessionFactory specified")
notNull(executorType, <span class="hljs-string">"No ExecutorType specified")
SqlSessionHolder holder = (SqlSessionHolder) getResource(sessionFactory)
<span class="hljs-keyword">if (holder != <span class="hljs-literal">null &&holder.isSynchronizedWithTransaction()) {
<span class="hljs-keyword">if (holder.getExecutorType() != executorType) {
<span class="hljs-keyword">throw <span class="hljs-keyword">new TransientDataAccessResourceException(<span class="hljs-string">"Cannot change the ExecutorType when there is an existing transaction")
}
holder.requested()
<span class="hljs-keyword">if (logger.isDebugEnabled()) {
logger.<span class="hljs-keyword">debug(<span class="hljs-string">"Fetched SqlSession [" + holder.getSqlSession() + <span class="hljs-string">"] from current transaction")
}
<span class="hljs-keyword">return holder.getSqlSession()
}
<span class="hljs-keyword">if (logger.isDebugEnabled()) {
logger.<span class="hljs-keyword">debug(<span class="hljs-string">"Creating a new SqlSession")
}
SqlSession session = sessionFactory.openSession(executorType)
<span class="hljs-comment">// Register session holder if synchronization is active (i.e. a Spring TX is active)
<span class="hljs-comment">//
<span class="hljs-comment">// Note: The DataSource used by the Environment should be synchronized with the
<span class="hljs-comment">// transaction either through DataSourceTxMgr or another tx synchronization.
<span class="hljs-comment">// Further assume that if an exception is thrown, whatever started the transaction will
<span class="hljs-comment">// handle closing / rolling back the Connection associated with the SqlSession.
<span class="hljs-keyword">if (isSynchronizationActive()) {
Environment environment = sessionFactory.getConfiguration().getEnvironment()
<span class="hljs-keyword">if (environment.getTransactionFactory() instanceof SpringManagedTransactionFactory) {
<span class="hljs-keyword">if (logger.isDebugEnabled()) {
logger.<span class="hljs-keyword">debug(<span class="hljs-string">"Registering transaction synchronization for SqlSession [" + session + <span class="hljs-string">"]")
}
holder = <span class="hljs-keyword">new SqlSessionHolder(session, executorType, exceptionTranslator)
bindResource(sessionFactory, holder)
registerSynchronization(<span class="hljs-keyword">new SqlSessionSynchronization(holder, sessionFactory))
holder.setSynchronizedWithTransaction(<span class="hljs-literal">true)
holder.requested()
} <span class="hljs-keyword">else {
<span class="hljs-keyword">if (getResource(environment.getDataSource()) == <span class="hljs-literal">null) {
<span class="hljs-keyword">if (logger.isDebugEnabled()) {
logger.<span class="hljs-keyword">debug(<span class="hljs-string">"SqlSession [" + session + <span class="hljs-string">"] was not registered for synchronization because DataSource is not transactional")
}
} <span class="hljs-keyword">else {
<span class="hljs-keyword">throw <span class="hljs-keyword">new TransientDataAccessResourceException(
<span class="hljs-string">"SqlSessionFactory must be using a SpringManagedTransactionFactory in order to use Spring transaction synchronization")
}
}
} <span class="hljs-keyword">else {
<span class="hljs-keyword">if (logger.isDebugEnabled()) {
logger.<span class="hljs-keyword">debug(<span class="hljs-string">"SqlSession [" + session + <span class="hljs-string">"] was not registered for synchronization because synchronization is not active")
}
}
<span class="hljs-keyword">return session
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>
会话(session)和事务的区别 一个session可以启动多个事务,session指一次连接。一个session中可以完成多个事务。 一个事务 是指一个 *** 作单元,要么成功,要么失败,没有中间状态。 会话,在应用程序中连接数据库要执行连接,然后会关闭,这算一次会话。 事务呢,就好比在打开会话后要执行程序中的某一个或多个对数据库进行的 *** 作欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)