У меня есть одна база данных с 3 схемами (OPS, TEST, TRAIN).Все эти схемы имеют полностью идентичную структуру таблицы.Теперь допустим, что у меня есть конечная точка / автомобили, которая принимает параметр запроса для схемы / среды.Когда пользователь делает запрос GET к этой конечной точке, мне нужно, чтобы бэкэнд Spring Boot имел возможность динамического доступа к схеме OPS, TEST или TRAIN на основе параметра запроса, указанного в запросе клиента.
Идея примерно такая, когда среда передается в качестве параметра запроса конечной точке, а затем каким-то образом используется в коде для установки источника схемы / данных, который будет использовать хранилище.
@Autowired
private CarsRepository carsRepository;
@GetMapping("/cars")
public List<Car> getCars(@RequestParam String env) {
setSchema(env);
return carsRepository.findAll();
}
private setSchema(String env) {
// Do something here to set the schema that the CarsRepository
// will use when it runs the .findAll() method.
}
Итак, есликлиент сделал запрос GET к конечной точке / cars с параметром запроса env, установленным в «OPS», тогда ответом будет список всех автомобилей в схеме OPS.Если клиент сделал тот же запрос, но с параметром запроса env, установленным на "TEST", то ответом будут все машины в схеме TEST.
Ниже приведен пример конфигурации источника данных.Это для схемы OPS.Другие схемы выполняются таким же образом, но без аннотации @Primary над компонентами.
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "opsEntityManagerFactory",
transactionManagerRef = "opsTransactionManager",
basePackages = { "com.example.repo" }
)
public class OpsDbConfig {
@Autowired
private Environment env;
@Primary
@Bean(name = "opsDataSource")
@ConfigurationProperties(prefix = "db-ops.datasource")
public DataSource dataSource() {
return DataSourceBuilder
.create()
.url(env.getProperty("db-ops.datasource.url"))
.driverClassName(env.getProperty("db-ops.database.driverClassName"))
.username(env.getProperty("db-ops.database.username"))
.password(env.getProperty("db-ops.database.password"))
.build();
}
@Primary
@Bean(name = "opsEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean opsEntityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier("opsDataSource") DataSource dataSource
) {
return builder
.dataSource(dataSource)
.packages("com.example.domain")
.persistenceUnit("ops")
.build();
}
@Primary
@Bean(name = "opsTransactionManager")
public PlatformTransactionManager opsTransactionManager(
@Qualifier("opsEntityManagerFactory") EntityManagerFactory opsEntityManagerFactory
) {
return new JpaTransactionManager(opsEntityManagerFactory);
}
}