当前位置:网站首页>Technology_ Multiple data sources

Technology_ Multiple data sources

2020-12-07 13:57:31 normalhefei

Some applications generally separate reading and writing . So for the program, it involves multiple data sources . The function of switching multiple data sources is encapsulated here

Realization

  1. Define multiple data sources And assign one key With the corresponding .
  2. The thread context stores the current Data sources key
  3. Realization AbstractRoutingDataSource rewrite determineCurrentLookupKey Method To retrieve from the thread context . And register to the spring Containers
  4. Convenience , Define an annotation @DataSource Put it in mybatis mapper Method signature is used to identify Which data source to use
  5. newly added mybatis plug-in unit ( Interceptor ), according to @DataSource Dynamically specify the data source used . The method is finished ThreadLocal Remember remove
  • Code

//  initialization   Multiple data sources , And rewrite to find   data source  key  The method to   From the thread context 
public class MultiRoutingDataSource extends AbstractRoutingDataSource {


    public MultiRoutingDataSource(Object defaultDataSource, Map<Object, Object> dataSources) {
        setDefaultTargetDataSource(defaultDataSource);
        Map<Object, Object> dses = Maps.newHashMap(MultiDsHolder.defaultDsKey, defaultDataSource);
        dses.putAll(dataSources);
        setTargetDataSources(dses);
    }

    @Override
    protected Object determineCurrentLookupKey() {
        return MultiDsHolder.get();
    }

}

//  Now interceptors ,  Dynamically specify data sources 
@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 MultiDsPlugin implements Interceptor {

    protected static final Logger logger = LoggerFactory.getLogger(MultiDsPlugin.class);


    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        DataSource annotation = invocation.getMethod().getAnnotation(DataSource.class);
        if (annotation != null) {
            String key = annotation.value();
            MultiDsHolder.set(key);
        } else {
            // If not, use the default 
            MultiDsHolder.set(MultiDsHolder.defaultDsKey);
        }
        Object rst = null;
        try {
            rst = invocation.proceed();
        } catch (Exception e) {
            logger.error("mybatis  Perform error :", e);
        } finally {
            MultiDsHolder.remove();
        }
        return rst;
    }


    @Override
    public Object plugin(Object target) {
        if (target instanceof Executor) {
            return Plugin.wrap(target, this);
        } else {
            return target;
        }
    }

    @Override
    public void setProperties(Properties properties) {
        //
    }
}

版权声明
本文为[normalhefei]所创,转载请带上原文链接,感谢
https://chowdera.com/2020/12/20201207135436120s.html