https://blog.51cto.com/12133802/2418053 使用即可 DynamicDataSource類 import org.springframework.jdbc.datasource.lo..."/>
溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

使用簡單的DataSource類配置主從服務(wù)器調(diào)用

發(fā)布時(shí)間:2020-07-16 03:37:55 來源:網(wǎng)絡(luò) 閱讀:537 作者:子非魚丶Y 欄目:編程語言

配置三個(gè)類

大家創(chuàng)建這三個(gè)類,配合> 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;

    }

    /**
     * 設(shè)置線程的DBType
     * @param str
     */
    public static void setDBType(String str) {
        logger.debug("所使用的數(shù)據(jù)源為:"+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是處理返回結(jié)果的
@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);

    //正則表達(dá)式,判斷是否是增刪改
    private static final String REGEX=".*insert\\u0020.*|.*delete\\u0020.*|.*update\\u0020.*";

    //什么情況去做攔截
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        //查看調(diào)用的方法是否使用了事物
        boolean synchronizationActive=TransactionSynchronizationManager.isActualTransactionActive();
        //獲取到方法的參數(shù)
        Object[] objects=invocation.getArgs();

        //增刪改查操作一般在頭部第一個(gè)會(huì)記錄,也就是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并返回這個(gè)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("設(shè)置方法 [{}] 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;
        }
    }

    //初始化時(shí)做相關(guān)設(shè)置
    @Override
    public void setProperties(Properties properties) {
        // TODO Auto-generated method stub

    }

}
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI