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>
声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。
E-MAIL:11247931@qq.com