Spring Boot 主從讀寫分離


自己封裝了一個讀寫分離的 Starter,可以配置任意多個數據源,使用 Hikari 連接池(暫不支持其他連接池)。

GitHub:rw-separate-spring-boot-starter

使用

Step 1. 添加 jitpack 到 pom.xml:

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://www.jitpack.io</url>
    </repository>
</repositories>

Step 2. 添加依賴:

<dependency>
    <groupId>com.github.imcloudfloating</groupId>
    <artifactId>rw-separate-spring-boot-starter</artifactId>
    <version>1.0.1</version>
</dependency>

首先需要排除默認的 DataSourceAutoConfiguration

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

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

不排除默認的 DataSource 會報沖突錯誤。

application.yml 配置

示例:

spring:
  separated-datasource:
    # 主庫數據源
    masters:
      - dataSourceName: master_1,
        hikari:
          driverClassName: com.mysql.cj.jdbc.Driver,
          url: jdbc:mysql://10.0.0.100:3306/test,
          username: root,
          password: root

    # 從庫數據源
    slaves:
      - dataSourceName: slave_1,
        hikari:
          driverClassName: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://10.0.0.101:3306/test
          username: reader
          password: reader
    
      - dataSourceName: slave_2
        hikari:
          driverClassName: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://10.0.0.102:3306/test
          username: reader
          password: reader
  • 以上配置文件中的 hikari 部分,可以參考 HikariConfig 類中的 setter 方法來填寫(首字母小寫)
  • dataSourceName 為數據源的名稱,請避免名稱重復(如果不需要顯式地指定數據源,可以不設置)
  • 當設置多個數據源時,默認使用輪詢的方式來切換數據源
  • 可以只設置 master ,使用名稱切換,當作多數據源使用,使用 @Write("datasource") 切換即可

使用注解實現讀寫分離

@Service
public class FooService {

    @Resource
    FooMapper fooMapper;
    
    /**
     * 使用讀庫
     */
    @Read
    public List<Item> getFoo() {
        return fooMapper.getAll();
    }

    /**
     * 使用寫庫
     */
    @Write
    public int addFoo(Foo foo) {
        return fooMapper.add(foo);
    }
}

可以使用參數顯式地指定數據源(需要在 application.yml 中指定 dataSourceName):

@Service
public class FooService {

    /**
     * 顯式地指定數據源為 master_1
     */
    @Write("master_1")
    public int addFoo(Foo foo) {
        return fooMapper.add(foo);
    }

}

顯式地指定數據源時,@Write 只能指定 masters 中的數據源,@Read 只能指定 slaves 中的數據源。

可以在 DAO 層使用,但是無法支持事務。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM