Spring Boot應用中如何動態指定資料庫,實現不同使用者不同資料庫的場景

程序猿DD發表於2024-04-26

當在 Spring Boot 應用程式中使用Spring Data JPA 進行資料庫操作時,配置Schema名稱是一種常見的做法。然而,在某些情況下,模式名稱需要是動態的,可能會在應用程式執行時發生變化。比如:需要做資料隔離的SaaS應用。

所以,這篇博文將幫助您解決了在 Spring Boot 應用程式中如何設定動態 Schema。

問題場景

假設,您的應用程式是一個SaaS軟體,需要為多個租戶提供服務,每個租戶都需要一個單獨的資料庫架構。

在這種情況下,在應用程式屬性中對Shema名稱進行硬編碼是不太可能的,這樣有一個使用者新增,就要去寫程式碼更新。

所以,為了應對這一挑戰,我們將探索一種允許在執行時動態配置模式名稱的解決方案。

我們建立了一個高質量的技術交流群,與優秀的人在一起,自己也會優秀起來,趕緊點選加群,享受一起成長的快樂。

程式碼案例

讓我們建立一個 Spring Boot 專案 首先設定一個具有必要依賴項的新 Spring Boot 專案。在專案配置中包括 Spring Web、Spring Data JPA 和關於資料庫的依賴項。

定義Spring Data JPA的實體類,例如:

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "product")
public class Product {
    @Id
    private Long id;
    private String name;
    private double price;

}

建立資料訪問介面,以便您的實體提供 CRUD 操作:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {

}

建立一個用來處理業務邏輯,包括與資料庫互動的方法:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ProductService {
    private final ProductRepository productRepository;

    @Autowired
    public ProductService(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }

    public List<Product> getAllProducts() {
        return productRepository.findAll();
    }

}

實現API介面:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/api/products")
public class ProductController {
    private final ProductService productService;

    @Autowired
    public ProductController(ProductService productService) {
        this.productService = productService;
    }

    @GetMapping
    public List<Product> getAllProducts() {
        return productService.getAllProducts();
    }

}

重點:配置動態Schema

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
public class DynamicSchemaConfig {

    @Value("${custom.schema.name}")
    private String customSchemaName;

    @Bean
    public DataSource dataSource() {
        String dataSourceUrl = "jdbc:mysql://localhost:3306/" + customSchemaName;
        return DataSourceBuilder.create().url(dataSourceUrl).build();
    }
}

重新打包該Spring Boot應用,然後當我們要為不同使用者使用完全隔離的資料庫、完全隔離的應用的時候,只需要透過下面的啟動命令,就能輕鬆實現了:

java -jar -Dcustom.schema.name=my_dynamic_schema your-application.jar

這裡,透過啟動命令中的custom.schema.name引數,就能去指定不同的資料庫Schema,而應用程式端都是同一套程式碼,由於啟動了新的Spring Boot應用,所以應用端程序也是完全隔離的。這種方法,對於使用Spring Boot構建需要一定資源隔離SaaS軟體來說,是個不錯的實現方案。

歡迎關注我的公眾號:程式猿DD。第一時間瞭解前沿行業訊息、分享深度技術乾貨、獲取優質學習資源

相關文章