Spring Boot應用中如何動態指定數據庫,實現不同用戶不同數據庫的場景

當在 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。第一時間瞭解前沿行業消息、分享深度技術乾貨、獲取優質學習資源

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章