中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

AbstractRoutingDataSource AOP如何實現動態數據源切換

發布時間:2021-07-02 17:03:09 來源:億速云 閱讀:232 作者:chen 欄目:大數據

本篇內容介紹了“AbstractRoutingDataSource AOP如何實現動態數據源切換”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

數據庫配置:application.properties
 

## datasource master #
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/master?characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456

## datasource slave #
spring.datasource-slave.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource-slave.driver-class-name=com.mysql.jdbc.Driver
spring.datasource-slave.url=jdbc:mysql://localhost:3306/slave?characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource-slave.username=root
spring.datasource-slave.password=123456

編寫數據庫名注解

public interface Datasources {
    String MASTER_DB = "masterDB";

    String SLAVE_DB = "slaveDB";
}

配置數據源

@Configuration
public class DataSourceConfig {
    //destroy-method="close"的作用是當數據庫連接不使用的時候,就把該連接重新放到數據池中,方便下次使用調用.
    @Bean(destroyMethod = "close", name = Datasources.MASTER_DB)
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().type(DruidDataSource.class).build();
    }

    @Bean(destroyMethod = "close", name = Datasources.SLAVE_DB)
    @ConfigurationProperties(prefix = "spring.datasource-slave")
    public DataSource dataSourceSlave() {
        return DataSourceBuilder.create().type(DruidDataSource.class).build();
    }
}

配置成動態數據源

@Configuration
@MapperScan(basePackages = {"com.example.dao"})
public class MybatisConfig {
    @Autowired
    @Qualifier(Datasources.MASTER_DB)
    private DataSource masterDB;

    @Autowired
    @Qualifier(Datasources.SLAVE_DB)
    private DataSource slaveDB;

    /**
     * 動態數據源
     */
    @Bean(name = "dynamicDataSource")
    public DataSource dynamicDataSource() {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        // 默認數據源
        dynamicDataSource.setDefaultTargetDataSource(masterDB);

        // 配置多數據源
        Map<Object, Object> dsMap = new HashMap<>();
        dsMap.put(Datasources.MASTER_DB, masterDB);
        dsMap.put(Datasources.SLAVE_DB, slaveDB);
        dynamicDataSource.setTargetDataSources(dsMap);

        return dynamicDataSource;
    }

    @Bean
    @ConfigurationProperties(prefix = "mybatis")
    public SqlSessionFactoryBean sqlSessionFactoryBean() {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // 配置數據源,此處配置為關鍵配置,如果沒有將 dynamicDataSource 作為數據源則不能實現切換
        sqlSessionFactoryBean.setDataSource(dynamicDataSource());
        return sqlSessionFactoryBean;
    }
}

使用ThreadLocal安全的管理當前進程使用的數據源連接

public class DataSourceContextHolder {
    /**
     * 默認數據源
     */
    public static final String DEFAULT_DATASOURCE = Datasources.MASTER_DB;

    private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();

    // 設置數據源名
    public static void setDB(String dbType) {
        System.out.println("切換到{}數據源:" +  dbType);
        contextHolder.set(dbType);
    }

    // 獲取數據源名
    public static String getDB() {
        return (contextHolder.get());
    }

    // 清除數據源名
    public static void clearDB() {
        contextHolder.remove();
    }
}

通過編寫切面,對所有我們自定義切庫注解的方法進行攔截,動態的選擇數據源

@Aspect
@Component
public class DynamicDataSourceAspect {

    @Before("@annotation(com.example.util.RoutingDataSource)")
    public void beforeSwitchDS(JoinPoint joinPoint) {

        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        String dataSource = DataSourceContextHolder.DEFAULT_DATASOURCE;
        if (method.isAnnotationPresent(RoutingDataSource.class)) {
            RoutingDataSource routingDataSource = method.getDeclaredAnnotation(RoutingDataSource.class);
            dataSource = routingDataSource.value();
        }
        DataSourceContextHolder.setDB(dataSource);
    }

    @After("@annotation(com.example.util.RoutingDataSource)")
    public void afterSwitchDS(JoinPoint point) {
        DataSourceContextHolder.clearDB();
    }
}

動態的取出我們在切面里設置的數據源的字符串

public class DynamicDataSource extends AbstractRoutingDataSource{
    @Override
    protected Object determineCurrentLookupKey() {
        System.out.println("數據源為{}:" + DataSourceContextHolder.getDB());
        return DataSourceContextHolder.getDB();
    }
}

取消自動配置數據源,使用我們這里定義的數據源配置

@SpringBootApplication(exclude = {
      DataSourceAutoConfiguration.class
})
public class CutDataBaseApplication {

   public static void main(String[] args) {
      SpringApplication.run(CutDataBaseApplication.class, args);
   }
}

使用

/**
 * @author aYong
 * @version 1.0
 * @date 2019/7/24
 */
@RestController
@RequestMapping("/route")
public class SysUserController {
    @Autowired
    private SysUserService sysUserService;

    @GetMapping("/test1")
    public SysUser test1(long id) {
        return sysUserService.test1(id);
    }

    @GetMapping("/test2")
    public Integer test2(long id, String name) {
        return sysUserService.test2(id, name);
    }
}

“AbstractRoutingDataSource AOP如何實現動態數據源切換”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

aop
AI

化德县| 长兴县| 泸西县| 石棉县| 合阳县| 顺平县| 德昌县| 南召县| 淳安县| 麻江县| 呼伦贝尔市| 九寨沟县| 福建省| 乌兰察布市| 三原县| 宝应县| 弥渡县| SHOW| 龙南县| 华阴市| 淳化县| 通道| 遵化市| 开鲁县| 晋江市| 福清市| 东山县| 藁城市| 酉阳| 马龙县| 揭东县| 临颍县| 泊头市| 班戈县| 邹平县| 巴彦淖尔市| 长阳| 沂源县| 合阳县| 大新县| 互助|