Spring3 整合MyBatis3 配置多数据源 动态选择SqlSessionFactory

您所在的位置:网站首页 mybatis选择数据源 Spring3 整合MyBatis3 配置多数据源 动态选择SqlSessionFactory

Spring3 整合MyBatis3 配置多数据源 动态选择SqlSessionFactory

2024-07-07 11:19:57| 来源: 网络整理| 查看: 265

Spring3 整合MyBatis3 配置多数据源 动态选择SqlSessionFactory

一、摘要

上两篇文章分别介绍了Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法 和 Spring3 整合Hibernate3.5 动态切换SessionFactory (切换数据库方言),这篇文章将介绍Spring整合Mybatis 如何完成SqlSessionFactory的动态切换的。并且会简单的介绍下MyBatis整合Spring中的官方的相关代码。

Spring整合MyBatis切换SqlSessionFactory有两种方法,第一、 继承SqlSessionDaoSupport,重写获取SqlSessionFactory的方法。第二、继承SqlSessionTemplate 重写getSqlSessionFactory、getConfiguration和SqlSessionInterceptor这个拦截器。其中最为关键还是继承SqlSessionTemplate 并重写里面的方法。

而Spring整合MyBatis也有两种方式,一种是配置MapperFactoryBean,另一种则是利用MapperScannerConfigurer进行扫描接口或包完成对象的自动创建。相对来说后者更方便些。MapperFactoryBean继承了SqlSessionDaoSupport也就是动态切换SqlSessionFactory的第一种方法,我们需要重写和实现SqlSessionDaoSupport方法,或者是继承MapperFactoryBean来重写覆盖相关方法。如果利用MapperScannerConfigurer的配置整合来切换SqlSessionFactory,那么我们就需要继承SqlSessionTemplate,重写上面提到的方法。在整合的配置中很多地方都是可以注入SqlSessionTemplate代替SqlSessionFactory的注入的。因为SqlSessionTemplate的创建也是需要注入SqlSessionFactory的。

 

二、实现代码

1、继承SqlSessionTemplate 重写getSqlSessionFactory、getConfiguration和SqlSessionInterceptor

package com.hoo.framework.mybatis.support; import static java.lang.reflect.Proxy.newProxyInstance;import static org.apache.ibatis.reflection.ExceptionUtil.unwrapThrowable;import static org.mybatis.spring.SqlSessionUtils.closeSqlSession;import static org.mybatis.spring.SqlSessionUtils.getSqlSession;import static org.mybatis.spring.SqlSessionUtils.isSqlSessionTransactional; import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.sql.Connection;import java.util.List;import java.util.Map; import org.apache.ibatis.exceptions.PersistenceException;import org.apache.ibatis.executor.BatchResult;import org.apache.ibatis.session.Configuration;import org.apache.ibatis.session.ExecutorType;import org.apache.ibatis.session.ResultHandler;import org.apache.ibatis.session.RowBounds;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.mybatis.spring.MyBatisExceptionTranslator;import org.mybatis.spring.SqlSessionTemplate;import org.springframework.dao.support.PersistenceExceptionTranslator;import org.springframework.util.Assert; /** * function: 继承SqlSessionTemplate 重写相关方法 * @author hoojo * @createDate 2013-10-18 下午03:07:46 * @file CustomSqlSessionTemplate.java * @package com.hoo.framework.mybatis.support * @project SHMB * @blog http://blog.csdn.net/IBM_hoojo * @email [email protected] * @version 1.0 */public class CustomSqlSessionTemplate extends SqlSessionTemplate {  private final SqlSessionFactory sqlSessionFactory; private final ExecutorType executorType; private final SqlSession sqlSessionProxy; private final PersistenceExceptionTranslator exceptionTranslator;  private Map targetSqlSessionFactorys; private SqlSessionFactory defaultTargetSqlSessionFactory;  public void setTargetSqlSessionFactorys(Map targetSqlSessionFactorys) { this.targetSqlSessionFactorys = targetSqlSessionFactorys; }  public void setDefaultTargetSqlSessionFactory(SqlSessionFactory defaultTargetSqlSessionFactory) { this.defaultTargetSqlSessionFactory = defaultTargetSqlSessionFactory; }  public CustomSqlSessionTemplate(SqlSessionFactory sqlSessionFactory) { this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType()); }  public CustomSqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType) { this(sqlSessionFactory, executorType, new MyBatisExceptionTranslator(sqlSessionFactory.getConfiguration() .getEnvironment().getDataSource(), true)); }  public CustomSqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator) {  super(sqlSessionFactory, executorType, exceptionTranslator);  this.sqlSessionFactory = sqlSessionFactory; this.executorType = executorType; this.exceptionTranslator = exceptionTranslator; this.sqlSessionProxy = (SqlSession) newProxyInstance( SqlSessionFactory.class.getClassLoader(), new Class[] { SqlSession.class }, new SqlSessionInterceptor());  this.defaultTargetSqlSessionFactory = sqlSessionFactory; }  @Override public SqlSessionFactory getSqlSessionFactory() {  SqlSessionFactory targetSqlSessionFactory = targetSqlSessionFactorys.get(CustomerContextHolder.getContextType()); if (targetSqlSessionFactory != null) { return targetSqlSessionFactory; } else if (defaultTargetSqlSessionFactory != null) { return defaultTargetSqlSessionFactory; } else { Assert.notNull(targetSqlSessionFactorys, "Property 'targetSqlSessionFactorys' or 'defaultTargetSqlSessionFactory' are required"); Assert.notNull(defaultTargetSqlSessionFactory, "Property 'defaultTargetSqlSessionFactory' or 'targetSqlSessionFactorys' are required"); } return this.sqlSessionFactory; }  @Override public Configuration getConfiguration() { return this.getSqlSessionFactory().getConfiguration(); }  public ExecutorType getExecutorType() { return this.executorType; }  public PersistenceExceptionTranslator getPersistenceExceptionTranslator() { return this.exceptionTranslator; }  /** * {@inheritDoc} */ public T selectOne(String statement) { return this.sqlSessionProxy. selectOne(statement); }  /** * {@inheritDoc} */ public T selectOne(String statement, Object parameter) { return this.sqlSessionProxy. selectOne(statement, parameter); }  /** * {@inheritDoc} */ public Map selectMap(String statement, String mapKey) { return this.sqlSessionProxy. selectMap(statement, mapKey); }  /** * {@inheritDoc} */ public Map selectMap(String statement, Object parameter, String mapKey) { return this.sqlSessionProxy. selectMap(statement, parameter, mapKey); }  /** * {@inheritDoc} */ public Map selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) { return this.sqlSessionProxy. selectMap(statement, parameter, mapKey, rowBounds); }  /** * {@inheritDoc} */ public List selectList(String statement) { return this.sqlSessionProxy. selectList(statement); }  /** * {@inheritDoc} */ public List selectList(String statement, Object parameter) { return this.sqlSessionProxy. selectList(statement, parameter); }  /** * {@inheritDoc} */ public List selectList(String statement, Object parameter, RowBounds rowBounds) { return this.sqlSessionProxy. selectList(statement, parameter, rowBounds); }  /** * {@inheritDoc} */ public void select(String statement, ResultHandler handler) { this.sqlSessionProxy.select(statement, handler); }  /** * {@inheritDoc} */ public void select(String statement, Object parameter, ResultHandler handler) { this.sqlSessionProxy.select(statement, parameter, handler); }  /** * {@inheritDoc} */ public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) { this.sqlSessionProxy.select(statement, parameter, rowBounds, handler); }  /** * {@inheritDoc} */ public int insert(String statement) { return this.sqlSessionProxy.insert(statement); }  /** * {@inheritDoc} */ public int insert(String statement, Object parameter) { return this.sqlSessionProxy.insert(statement, parameter); }  /** * {@inheritDoc} */ public int update(String statement) { return this.sqlSessionProxy.update(statement); }  /** * {@inheritDoc} */ public int update(String statement, Object parameter) { return this.sqlSessionProxy.update(statement, parameter); }  /** * {@inheritDoc} */ public int delete(String statement) { return this.sqlSessionProxy.delete(statement); }  /** * {@inheritDoc} */ public int delete(String statement, Object parameter) { return this.sqlSessionProxy.delete(statement, parameter); }  /** * {@inheritDoc} */ public T getMapper(Class type) { return getConfiguration().getMapper(type, this); }  /** * {@inheritDoc} */ public void commit() { throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession"); }  /** * {@inheritDoc} */ public void commit(boolean force) { throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession"); }  /** * {@inheritDoc} */ public void rollback() { throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession"); }  /** * {@inheritDoc} */ public void rollback(boolean force) { throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession"); }  /** * {@inheritDoc} */ public void close() { throw new UnsupportedOperationException("Manual close is not allowed over a Spring managed SqlSession"); }  /** * {@inheritDoc} */ public void clearCache() { this.sqlSessionProxy.clearCache(); }  /** * {@inheritDoc} */ public Connection getConnection() { return this.sqlSessionProxy.getConnection(); }  /** * {@inheritDoc} * @since 1.0.2 */ public List flushStatements() { return this.sqlSessionProxy.flushStatements(); }  /** * Proxy needed to route MyBatis method calls to the proper SqlSession got from Spring's Transaction Manager It also * unwraps exceptions thrown by {@code Method#invoke(Object, Object...)} to pass a {@code PersistenceException} to * the {@code PersistenceExceptionTranslator}. */ private class SqlSessionInterceptor implements InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { final SqlSession sqlSession = getSqlSession( CustomSqlSessionTemplate.this.getSqlSessionFactory(), CustomSqlSessionTemplate.this.executorType, CustomSqlSessionTemplate.this.exceptionTranslator); try { Object result = method.invoke(sqlSession, args); if (!isSqlSessionTransactional(sqlSession, CustomSqlSessionTemplate.this.getSqlSessionFactory())) { // force commit even on non-dirty sessions because some databases require // a commit/rollback before calling close() sqlSession.commit(true); } return result; } catch (Throwable t) { Throwable unwrapped = unwrapThrowable(t); if (CustomSqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) { Throwable translated = CustomSqlSessionTemplate.this.exceptionTranslator .translateExceptionIfPossible((PersistenceException) unwrapped); if (translated != null) { unwrapped = translated; } } throw unwrapped; } finally { closeSqlSession(sqlSession, CustomSqlSessionTemplate.this.getSqlSessionFactory()); } } } }

重写后的getSqlSessionFactory方法会从我们配置的SqlSessionFactory集合targetSqlSessionFactorys或默认的defaultTargetSqlSessionFactory中获取Session对象。而改写的SqlSessionInterceptor 是这个MyBatis整合Spring的关键,所有的SqlSessionFactory对象的session都将在这里完成创建、提交、关闭等操作。所以我们改写这里的代码,在这里获取getSqlSessionFactory的时候,从多个SqlSessionFactory中获取我们设置的那个即可。

上面添加了targetSqlSessionFactorys、defaultTargetSqlSessionFactory两个属性来配置多个SqlSessionFactory对象和默认的SqlSessionFactory对象。

 

CustomerContextHolder 设置SqlSessionFactory的类型

package com.hoo.framework.mybatis.support; /** * function: 多数据源 * @author hoojo * @createDate 2013-9-27 上午11:36:57 * @file CustomerContextHolder.java * @package com.hoo.framework.spring.support * @project SHMB * @blog http://blog.csdn.net/IBM_hoojo * @email [email protected] * @version 1.0 */public abstract class CustomerContextHolder {  public final static String SESSION_FACTORY_MYSQL = "mysql"; public final static String SESSION_FACTORY_ORACLE = "oracle"; private static final ThreadLocal contextHolder = new ThreadLocal(); public static void setContextType(String contextType) { contextHolder.set(contextType); } public static String getContextType() { return contextHolder.get(); } public static void clearContextType() { contextHolder.remove(); } }

 

2、配置相关的文件applicationContext-session-factory.xml



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭