一、配置多个sessionFactory
1、配置多个dataSource,配置多个sessionFactory,配置多个事务管理器;形成独立的几套数据库连接
2、如果是面向接口形式的查询,直接将用sessionFactory扫描对应的sql文件即可
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="multipleDs" />
<property name="configLocation" value="classpath:spring/mybatis-config.xml"></property>
<property name="mapperLocations">
<array>
<value>classpath:mapper/*.xml</value>
</array>
</property>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageHelper">
<property name="properties">
<value>
dialect=mysql
reasonable=false
</value>
</property>
</bean>
</array>
</property>
</bean>
3、如果是使用sqlId执行的,在dao层注入不同的sessionFacatory即可
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pb.base.exception.DaoException;
/**
* @author
* 基类Dao,对Mybatis方法进行客户化
* 2016-06-25
*/
@Repository("executeSqlDao")
@SuppressWarnings(value="rawtypes")
public class ExecuteSqlDao extends SqlSessionDaoSupport{
/**
* 批量插入数量最大值
*/
public static final int INSERT_BATCH_SIZE_MAX_NUM = 1000;
/**
* 批量更新数量最大值
*/
public static final int UPDATE_BATCH_SIZE_MAX_NUM = 1000;
/**
* 批量删除数量最大值
*/
public static final int DELETE_BATCH_SIZE_MAX_NUM = 1000;
// @Resource
private TransactionTemplate transactionTemplate;
private Logger logger = LoggerFactory.getLogger(ExecuteSqlDao.class);
@Autowired
public ExecuteSqlDao(
@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
super.setSqlSessionFactory(sqlSessionFactory);
}
二、基于多数据源形式
1、配置多个dataSource
<!-- smt业务库 -->
<bean id="smtDataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<!-- 数据库基本信息配置 -->
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
2、创建多数据源
<!-- 配置多数据源 -->
<bean id="multipleDs"
class="com.pb.base.dao.MultiDsHandler">
<property name="targetDataSources">
<map>
<entry key="smt" value-ref="smtDataSource" />
<entry key="test" value-ref="testDataSource" />
</map>
</property>
</bean>
MultiDsHandler是需要手动实现的数据库跳转方法
3、将多数据源配置到sessionFactory和事务处理器中
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="multipleDs" />
<property name="configLocation" value="classpath:spring/mybatis-config.xml"></property>
<property name="mapperLocations">
<array>
<value>classpath:mapper/*.xml</value>
</array>
</property>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageHelper">
<property name="properties">
<value>
dialect=mysql
reasonable=false
</value>
</property>
</bean>
</array>
</property>
</bean>
<!-- 定义事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="multipleDs"></property>
</bean>
4、数据源切换类com.pb.base.dao.MultiDsHandler
import java.util.HashMap;
import java.util.Map;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
@SuppressWarnings({"rawtypes","unchecked"})
public class MultiDsHandler extends AbstractRoutingDataSource {
public static final String DS_NO = "dsNo";
private static final ThreadLocal<Map> threadLocal = new ThreadLocal<Map>();
@Override
protected Object determineCurrentLookupKey() {
if (null != threadLocal) {
Map threadVars = threadLocal.get();
if(threadVars == null){
return MultiDsUtil.SMT_DATA_SOURCE;
}else{
String dsNo = (String) threadVars.get(MultiDsHandler.DS_NO);
return dsNo;
}
} else {
return "";
}
}
public static void switchDsKey(String dsKey) {
Map threadVars = threadLocal.get();
if (null != threadVars) {
threadVars.put(MultiDsHandler.DS_NO, dsKey);
} else {
threadVars = new HashMap();
threadVars.put(MultiDsHandler.DS_NO, dsKey);
threadLocal.set(threadVars);
}
}
public static Map getThreadVars() {
return threadLocal.get();
}
}
5、对Dao层方法的执行增加拦截器
保证执行前切换到对的数据库(将数据库的key值当道线程变量中)
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import com.pb.base.dao.MultiDsHandler;
import com.pb.base.dao.MultiDsUtil;
/**
* 方法执行时间切面
*
* @author Administrator
*
*/
@Component
@Aspect
@Order(value = 0)
public class ExecuteSqlDaoSwith {
Logger logger = LoggerFactory.getLogger(ExecuteSqlDaoSwith.class);
/**
* 动态数据源切换,切换到公共库
*/
@Before("execution(* com.pb.base.dao.ExecuteSqlDao.*(..))")
public void dsSwitch(JoinPoint joinPoint){
MultiDsHandler.switchDsKey(MultiDsUtil.SMT_DATA_SOURCE);
logger.info("数据源切换,当前数据源【{}】",MultiDsUtil.SMT_DATA_SOURCE);
}
}