Spring Boot REST: Как динамически получить доступ к соответствующей схеме базы данных, указанной в запросе клиента? - PullRequest
0 голосов
/ 28 января 2019

У меня есть одна база данных с 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);
}

}

Ответы [ 2 ]

0 голосов
/ 30 января 2019

Обычно вы не хотите, чтобы экземпляры TEST / ACPT работали на одних и тех же компьютерах, поскольку обычно становится все труднее [держать под контролем] контроль степени, в которой нагрузка в этих средах замедлит работу среды PROD.

Вы также не хотите, чтобы настройка, которую вы предусмотрели, потому что это делает почти невозможным развитие приложения и / или его структуры базы данных.(Вы не собираетесь переключать схему БД в PROD в то же самое время, когда вы делаете это в DEV, не так ли? Вы не делаете этого одновременного переключения разумно, но это нарушает ваше предположение, что «все три базы данных имеют абсолютно одинаковую схему».

0 голосов
/ 29 января 2019

Лично я не чувствую права передавать среду в качестве параметра запроса и переключать хранилище на основе переданного значения.

Вместо этого вы можете развернуть несколько экземпляров службы, указывающих на другой источник данных, и иметьсторож (маршрутизатор) для маршрутизации к соответствующему сервису.

Таким образом, клиенты получат доступ к одной службе шлюза, которая, в свою очередь, направляет к соответствующей службе на основе входных данных для гейткипера.

...