配置三个类

大家创建这三个类,配合> https://blog.51cto.com/12133802/2418053 使用即可

DynamicDataSource类

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicDataSource extends AbstractRoutingDataSource{ @Override protected Object determineCurrentLookupKey() { // TODO Auto-generated method stub return DynamicDataSourceHolder.getDBType(); }}DynamicDataSourceHolder类

import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class DynamicDataSourceHolder { private static Logger logger=LoggerFactory.getLogger(DynamicDataSourceHolder.class); private static ThreadLocal<String> contextHolder=new ThreadLocal<String>(); public static final String DB_MASTER = "master"; public static final String DB_SLAVE="slave"; public static String getDBType() { String db=contextHolder.get(); if(db==null) { db=DB_MASTER; } return db; } /** * 设置线程的DBType * @param str */ public static void setDBType(String str) { logger.debug("所使用的数据源为:"+str); contextHolder.set(str); } /** * 清理线程 */ public static void clearDBType() { contextHolder.remove(); }DynamicDataSourceInterceptor拦截器类

import java.util.Locale;import java.util.Properties;import org.apache.ibatis.executor.Executor;import org.apache.ibatis.executor.keygen.SelectKeyGenerator;import org.apache.ibatis.mapping.BoundSql;import org.apache.ibatis.mapping.MappedStatement;import org.apache.ibatis.mapping.SqlCommandType;import org.apache.ibatis.plugin.Interceptor;import org.apache.ibatis.plugin.Intercepts;import org.apache.ibatis.plugin.Invocation;import org.apache.ibatis.plugin.Plugin;import org.apache.ibatis.plugin.Signature;import org.apache.ibatis.session.ResultHandler;import org.apache.ibatis.session.RowBounds;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.transaction.support.TransactionSynchronizationManager;//增删改的操作都在update里面,RowBounds.class,ResultHandler.class是处理返回结果的@Intercepts({ @Signature(type=Executor.class,method="update",args= {MappedStatement.class,Object.class}), @Signature(type=Executor.class,method="query",args= {MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class})})public class DynamicDataSourceInterceptor implements Interceptor{ private static Logger logger=LoggerFactory.getLogger(DynamicDataSourceInterceptor.class); //正则表达式,判断是否是增删改 private static final String REGEX=".*insert\\u0020.*|.*delete\\u0020.*|.*update\\u0020.*"; //什么情况去做拦截 @Override public Object intercept(Invocation invocation) throws Throwable { //查看调用的方法是否使用了事物 boolean synchronizationActive=TransactionSynchronizationManager.isActualTransactionActive(); //获取到方法的参数 Object[] objects=invocation.getArgs(); //增删改查操作一般在头部第一个会记录,也就是object[0]中可以获取的到 MappedStatement ms=(MappedStatement)objects[0]; String lookupKey=DynamicDataSourceHolder.DB_MASTER; //读方法 if(synchronizationActive!=true) { if(ms.getSqlCommandType().equals(SqlCommandType.SELECT)) { //selectKey为自增ID查询主键(SELECT LAST_INSERT_ID())方法,使用主库 //就是添加例如商品信息,自增ID并返回这个ID的情况 if(ms.getId().contains(SelectKeyGenerator.SELECT_KEY_SUFFIX)) { lookupKey=DynamicDataSourceHolder.DB_MASTER; }else { BoundSql boundSql=ms.getSqlSource().getBoundSql(objects[1]); String sql=boundSql.getSql().toLowerCase(Locale.CHINA).replaceAll("[\\t\\n\\r]"," "); //使用正则判断 if(sql.matches(REGEX)) { //主库 lookupKey=DynamicDataSourceHolder.DB_MASTER; }else { //从库 lookupKey=DynamicDataSourceHolder.DB_SLAVE; } } } }else { lookupKey=DynamicDataSourceHolder.DB_MASTER; } logger.debug("设置方法 [{}] use [{}] Strategy,SqlCommanType [{}]",ms.getId(),lookupKey, ms.getSqlCommandType().name()); DynamicDataSourceHolder.setDBType(lookupKey); return invocation.proceed(); } //是否使用代理包装 @Override public Object plugin(Object target) { if(target instanceof Executor) { return Plugin.wrap(target, this); }else { return target; } } //初始化时做相关设置 @Override public void setProperties(Properties properties) { // TODO Auto-generated method stub }}