• Java Mybatis实现主从同步


    import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
    
    public class DynamicDataSource extends AbstractRoutingDataSource{
    
    	@Override
    	protected Object determineCurrentLookupKey(){
    		return DynamicDataSourceHolder.getDbType();
    	}
    }
    

      

    import org.slf4j.LoggerFactory;
    import org.slf4j.Logger;
    
    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;
        }
        public static void setDbType(String str){
        	logger.debug("所使用的数据源为:"+str);
        	contextHolder.set(str);
        }
        //清理连接类型
        public static void clearDBType(){
        	contextHolder.remove();
        }
        
    }
    

      

    import java.util.Locale;
    import java.util.Properties;
    import java.util.concurrent.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.Invocation;
    import org.apache.ibatis.plugin.Plugin;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.transaction.support.TransactionSynchronizationManager;
    
    /**
     * @author wls
     *
     */

    @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.*|.8update\u0020.*";
    
    	@Override
    	public Object intercept(Invocation invocation) throws Throwable {
    		//判断当前是不是事物
    		boolean synchronizatioinActive=TransactionSynchronizationManager.
    				isActualTransactionActive();
    		Object[] objects= invocation.getArgs();
    		MappedStatement ms=(MappedStatement)objects[0];
    		String lookupKey=DynamicDataSourceHolder.DB_MASTER;
    		if(synchronizatioinActive!=true){
    			
    			//读方法
    			if(ms.getSqlCommandType().equals(SqlCommandType.SELECT)){
    				//SELECT_KEY为自增id查询主键SELECT LAST_INSERT_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) {
    		// TODO Auto-generated method stub
    		if(target instanceof Executor){
    			return Plugin.wrap(target, this);
    		}else{
    			return target;
    		}
    	}
    
    	@Override
    	public void setProperties(Properties arg0) {
    		// TODO Auto-generated method stub
    		
    	}
    }
    

      配置:

     mybatis配置:

    <plugins>
    	<plugin interceptor="split.DynamicDataSourceInterceptor"></plugin>
    	</plugins>
    

      

  • 相关阅读:
    oracle笔记
    log4j配置
    前段页面性能标准
    递归多叉树遍历
    // 获取元素拒顶部高度
    window.parent
    webpack打包
    vue源码解析推荐文章
    在vue项目中。artTemplate引入失败问题,修改源码
    webpack打包css前缀自动取消,以及样式冲突问题
  • 原文地址:https://www.cnblogs.com/sunliyuan/p/10637460.html
Copyright © 2020-2023  润新知