mybatis中怎么创建sqlsession
发布网友
发布时间:2022-04-20 03:53
我来回答
共1个回答
热心网友
时间:2022-04-08 04:35
首先, 通过翻阅源码,我们来整理一下mybatis进行持久化操作时重要的几个类:
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>