6

Spring Boot应用中如何动态指定数据库,实现不同用户不同数据库等场景

 4 months ago
source link: https://www.didispace.com/article/spring-boot/spring-data-jpa-dynamically-schema.html#%E4%BB%A3%E7%A0%81%E6%A1%88%E4%BE%8B
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

当在 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软件来说,是个不错的实现方案。

如果您学习过程中如遇困难?可以加入我们超高质量的Spring技术交流群open in new window,参与交流与讨论,更好的学习与进步!更多Spring Boot教程可以点击直达!open in new window,欢迎收藏与转发支持!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK