日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Spring Boot + MyBatis-Plus 實現 MySQL 主從復制動態數據源切換

來源: 責編: 時間:2023-12-13 17:01:59 240觀看
導讀MySQL 主從復制是一種常見的數據庫架構,它可以提高數據庫的性能和可用性。動態數據源切換則可以根據業務需求,在不同場景下使用不同的數據源,比如在讀多寫少的場景下,可以通過切換到從庫來分擔主庫的壓力。在本文中,我們將

MySQL 主從復制是一種常見的數據庫架構,它可以提高數據庫的性能和可用性。動態數據源切換則可以根據業務需求,在不同場景下使用不同的數據源,比如在讀多寫少的場景下,可以通過切換到從庫來分擔主庫的壓力。sHs28資訊網——每日最新資訊28at.com

在本文中,我們將介紹如何在 Spring Boot 中實現 MySQL 主從復制和動態數據源切換,使用 MyBatis-Plus 進行數據庫操作sHs28資訊網——每日最新資訊28at.com

#代碼地址https://github.com/bangbangzhou/spring-boot-dynamic-master-slave.git

今日內容介紹,大約花費19分鐘sHs28資訊網——每日最新資訊28at.com

圖片圖片sHs28資訊網——每日最新資訊28at.com

那么接下來我們開始項目實現,項目結構如下sHs28資訊網——每日最新資訊28at.com

圖片圖片sHs28資訊網——每日最新資訊28at.com

1.引入依賴

在項目的的pom.xml文件中引入Spring Boot和MyBatis-Plus的相關依賴sHs28資訊網——每日最新資訊28at.com

<?xml versinotallow="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <parent>        <artifactId>spring-boot-starter-parent</artifactId>        <groupId>org.springframework.boot</groupId>        <version>2.7.15</version>    </parent>    <groupId>com.zbbmeta</groupId>    <artifactId>spring-boot-dynamic-master-slave</artifactId>    <version>1.0-SNAPSHOT</version>    <properties>        <maven.compiler.source>11</maven.compiler.source>        <maven.compiler.target>11</maven.compiler.target>    </properties>    <dependencies>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-web</artifactId>        </dependency>        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>            <version>8.0.30</version>        </dependency>        <dependency>            <groupId>com.baomidou</groupId>            <artifactId>mybatis-plus-boot-starter</artifactId>            <version>3.5.3</version>        </dependency>        <dependency>            <groupId>cn.hutool</groupId>            <artifactId>hutool-all</artifactId>            <version>5.8.20</version>        </dependency>        <dependency>            <groupId>org.projectlombok</groupId>            <artifactId>lombok</artifactId>        </dependency>        <dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter-aop</artifactId>        </dependency>    </dependencies>    <build>        <plugins>            <plugin>                <groupId>org.springframework.boot</groupId>                <artifactId>spring-boot-maven-plugin</artifactId>                <configuration>                    <excludes>                        <exclude>                            <groupId>org.projectlombok</groupId>                            <artifactId>lombok</artifactId>                        </exclude>                    </excludes>                </configuration>            </plugin>        </plugins>    </build></project>

2. 配置數據源

在application.yml文件中配置主從數據源信息。注意這里我們要搭建主從數據庫,只是在一個mysql實例中創建兩個庫,里面存在相同表sHs28資訊網——每日最新資訊28at.com

server:  port: 8082spring:  datasource:    master:      username: root      password: root      url: jdbc:mysql://localhost:3306/shiro_db?useUnicode=true&characterEncoding=utf8      driver-class-name: com.mysql.cj.jdbc.Driver    slave:      username: root      password: root      url: jdbc:mysql://localhost:3306/backend_db?useUnicode=true&characterEncoding=utf8      driver-class-name: com.mysql.cj.jdbc.Drivermybatis-plus:  mapper-locations: classpath*:/mapper/**/*.xml

3. 創建DatabaseType 枚舉類型

創建DatabaseType 枚舉類型,用于切換數據源時,確定連接的是哪個數據源sHs28資訊網——每日最新資訊28at.com

在com.zbbmeta.config包下創建DatabaseType枚舉類型sHs28資訊網——每日最新資訊28at.com

// 定義一個枚舉類型 DatabaseType,表示系統中的數據庫類型public enum DatabaseType {    MASTER,  // 主數據庫類型    SLAVE    // 從數據庫類型}

4. 配置數據源上下文

在com.zbbmeta.holder包下創建一個DataSourceContextHolder類用于保存和獲取當前線程使用的數據源類型sHs28資訊網——每日最新資訊28at.com

public class DatabaseContextHolder {    private static final ThreadLocal<DatabaseType> contextHolder = new ThreadLocal<>();    public static void setDatabaseType(DatabaseType databaseType) {        contextHolder.set(databaseType);    }    public static DatabaseType getDatabaseType() {        return contextHolder.get();    }    public static void clearDatabaseType() {        contextHolder.remove();    }}

5. 配置動態數據源

我們創建了一個 DynamicDataSource 類,繼承 AbstractRoutingDataSource,用于實現動態數據源的切換。sHs28資訊網——每日最新資訊28at.com

AbstractRoutingDataSource 是 Spring Framework 提供的一個抽象數據源類,用于實現動態數據源切換。它允許應用程序在運行時動態地切換到不同的數據源,從而支持多數據源的場景,比如數據庫讀寫分離、主從復制等sHs28資訊網——每日最新資訊28at.com

AbstractRoutingDataSource介紹:sHs28資訊網——每日最新資訊28at.com

  • 動態數據源切換:AbstractRoutingDataSource 的核心思想是根據某個鍵值(lookup key)來決定使用哪個具體的數據源。這個鍵值是通過 determineCurrentLookupKey() 方法提供
  • 抽象類:AbstractRoutingDataSource 是一個抽象類,它提供了模板方法 determineCurrentLookupKey(),需要由子類實現
  • 實現 javax.sql.DataSource 接口:AbstractRoutingDataSource 實現了 javax.sql.DataSource 接口,因此可以像常規數據源一樣被用于與數據庫的交互。
  • 在 Spring 配置中使用:在 Spring 的配置中,我們可以將 AbstractRoutingDataSource 配置為數據源 bean,并將真實的數據源作為其目標數據源。在需要切換數據源的時候,調用 determineCurrentLookupKey() 方法,它將返回用于切換數據源的鍵值。

在com.zbbmeta.config包下創建DynamicDataSource類sHs28資訊網——每日最新資訊28at.com

public class DynamicDataSource extends AbstractRoutingDataSource {    @Override    protected Object determineCurrentLookupKey() {        return DataSourceContextHolder.getDataSourceType();    }}

DynamicDataSource類中重寫determineCurrentLookupKey()方法:在這個方法中,我們通過調用 DataSourceContextHolder.getDataSourceType() 來獲取當前線程持有的數據源類型。這個方法的返回值將被用作數據源的 lookup key,從而實現動態切換。sHs28資訊網——每日最新資訊28at.com

6. 添加DataSource注解類

在·com.zbbmeta.annotation包下創建DataSource注解類,這是一個自定義注解,用于標記在類或方法上,以指定數據源的類型。下面是對這段代碼的注解說明sHs28資訊網——每日最新資訊28at.com

@Target({ ElementType.METHOD, ElementType.TYPE })@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface DataSource {    DatabaseType type() default DatabaseType.SLAVE;}

注解說明:sHs28資訊網——每日最新資訊28at.com

  • @interface DataSource:這是一個注解的聲明,用于創建名為 DataSource 的自定義注解。
  • @Target({ElementType.METHOD, ElementType.TYPE}):@Target 注解表示此注解可以用于類和方法。在這里,DataSource 注解可以標注在類和方法上。
  • @Retention(RetentionPolicy.RUNTIME):@Retention 注解表示這個注解的生命周期,即在運行時仍然可用。這是因為我們希望在運行時通過反射獲取注解信息。
  • DatabaseType type() default DatabaseType.SLAVE:這是 DataSource 注解的一個成員變量。它是一個枚舉類型的變量,表示數據庫類型,默認值為 SLAVE。通過這個成員變量,我們可以在使用 DataSource 注解時指定使用的數據源類型

7. 配置數據源切換切面

在com.zbbmeta.aspect包下創建一個切面類DataSourceAspect,用于在執行數據庫操作前動態切換數據源。sHs28資訊網——每日最新資訊28at.com

@Aspect@Component@EnableAspectJAutoProxypublic class DataSourceAspect {// 定義切點,匹配使用了 @DataSource 注解的方法    @Pointcut("@annotation(com.zbbmeta.annotation.DataSource)")    public void dataSourcePointCut() {}    // 環繞通知,在方法執行前后切換數據源    @Around("dataSourcePointCut()")    public Object around(ProceedingJoinPoint point) throws Throwable {        MethodSignature signature = (MethodSignature) point.getSignature();        Method method = signature.getMethod();        // 獲取方法上的 @DataSource 注解        DataSource dataSource = method.getAnnotation(DataSource.class);        if (dataSource != null) {            // 切換數據源類型            DatabaseContextHolder.setDatabaseType(dataSource.type());        }        try {            // 執行目標方法            return point.proceed();        } finally {            // 清除數據源類型,確保線程安全            DatabaseContextHolder.clearDatabaseType();        }    }}

8. 創建DataSourceConfig

在com.zbbmeta.config包下創建DataSourceConfig,用于配置主從兩個數據源sHs28資訊網——每日最新資訊28at.com

@Configuration@Datapublic class DataSourceConfig {    @Value("${spring.datasource.master.url}")    private String dbUrl;    @Value("${spring.datasource.master.username}")    private String username;    @Value("${spring.datasource.master.password}")    private String password;    @Value("${spring.datasource.master.driver-class-name}")    private String driverClassName;    @Value("${spring.datasource.slave.url}")    private String slaveDbUrl;    @Value("${spring.datasource.slave.username}")    private String slaveUsername;    @Value("${spring.datasource.slave.password}")    private String slavePassword;    @Value("${spring.datasource.slave.driver-class-name}")    private String slaveDriverClassName;    @Bean    @ConfigurationProperties(prefix = "spring.datasource.master")    public DataSource masterDataSource() {        return DataSourceBuilder.create()                .driverClassName(driverClassName)                .url(dbUrl)                .username(username)                .password(password)                .build();    }    @Bean    @ConfigurationProperties(prefix = "spring.datasource.slave")    public DataSource slaveDataSource() {        return DataSourceBuilder.create()                .driverClassName(slaveDriverClassName)                .url(slaveDbUrl)                .username(slaveUsername)                .password(slavePassword)                .build();    }}

9 創建DataSourceConfig

在com.zbbmeta.config包下創建DynamicDataSourceConfig類中配置MyBatis-Plus的相關內容。sHs28資訊網——每日最新資訊28at.com

@Configuration@MapperScan("com.zbbmeta.mapper")public class DynamicDataSourceConfig {    @Autowired    private DataSource masterDataSource;    @Autowired    private DataSource slaveDataSource;    // 配置動態數據源    @Bean    @Primary    public DataSource dynamicDataSource() {        Map<Object, Object> targetDataSources = new HashMap<>();        targetDataSources.put(DatabaseType.MASTER, masterDataSource);        targetDataSources.put(DatabaseType.SLAVE, slaveDataSource);        DynamicRoutingDataSource dynamicDataSource = new DynamicRoutingDataSource();        dynamicDataSource.setTargetDataSources(targetDataSources);        dynamicDataSource.setDefaultTargetDataSource(masterDataSource); // 設置默認數據源        return dynamicDataSource;    }    // 配置 MyBatis 的 SqlSessionFactory    @Bean    public SqlSessionFactory sqlSessionFactory(DataSource dynamicDataSource) throws Exception {        MybatisSqlSessionFactoryBean sessionFactoryBean = new MybatisSqlSessionFactoryBean();        sessionFactoryBean.setDataSource(dynamicDataSource);        // 設置要掃描的 mapper 接口和 XML 文件路徑        sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));        sessionFactoryBean.setTypeAliasesPackage("com.zbbmeta.entity");  // 設置實體類包路徑        return sessionFactoryBean.getObject();    }    // 配置 MyBatis 的 SqlSessionTemplate    @Bean    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {        return new SqlSessionTemplate(sqlSessionFactory);    }}

10. 測試

使用MybatisX生成代碼,并且創建com.zbbmeta.controller包下創建TutorialController類,并且在需要切換數據源的方法上使用 @DataSource 注解,切面將根據該注解的配置在方法執行前后進行數據源切換。sHs28資訊網——每日最新資訊28at.com

圖片圖片sHs28資訊網——每日最新資訊28at.com

圖片圖片sHs28資訊網——每日最新資訊28at.com

@RestControllerpublic class TutorialController {    @Autowired    private TutorialService tutorialService;    @DataSource    @GetMapping("/list")    public List<Tutorial> list(){        return tutorialService.list();    }    @DataSource(type = DatabaseType.MASTER)    @GetMapping("/create")    public Boolean create(){        Tutorial tutorial = new Tutorial();        tutorial.setTitle("master");        tutorial.setDescription("master");        return tutorialService.save(tutorial);    }}

使用POSTMAN發送請求sHs28資訊網——每日最新資訊28at.com

http://localhost:8082/listhttp://localhost:8082/create
#代碼地址https://github.com/bangbangzhou/spring-boot-dynamic-master-slave.git

sHs28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-44394-0.htmlSpring Boot + MyBatis-Plus 實現 MySQL 主從復制動態數據源切換

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 原生 CSS 中類似 Sass 的嵌套

下一篇: C++之函數模板

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 随州市| 丁青县| 日土县| 云龙县| 承德县| 靖州| 吴川市| 图木舒克市| 清流县| 富锦市| 喀喇| 朝阳市| 湘乡市| 中宁县| 秦皇岛市| 鄂伦春自治旗| 延安市| 万全县| 台南县| 温州市| 夏邑县| 诸城市| 桃江县| 龙山县| 蓬莱市| 桓台县| 嘉兴市| 玉树县| 哈巴河县| 甘德县| 泰安市| 饶河县| 卓尼县| 衡阳县| 衡水市| 峡江县| 芜湖市| 清新县| 富源县| 延吉市| 海南省|