gpt4 book ai didi

java - 在 Spring Boot 应用程序的多个数据库中未创建表

转载 作者:IT老高 更新时间:2023-10-28 13:47:29 27 4
gpt4 key购买 nike

我正在开发 Spring Boot Multi-Tenancy 应用程序。我已经配置了多个数据源,如下所示:

application.properties

spring.multitenancy.datasource1.url=jdbc:mysql://localhost:3306/db1
spring.multitenancy.datasource1.username=root
spring.multitenancy.datasource1.password=****
spring.multitenancy.datasource1.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update

spring.multitenancy.datasource2.url=jdbc:mysql://localhost:3306/db2
spring.multitenancy.datasource2.username=root
spring.multitenancy.datasource2.password=****
spring.multitenancy.datasource2.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update

spring.multitenancy.datasource3.url=jdbc:mysql://localhost:3306/db3
spring.multitenancy.datasource3.username=root
spring.multitenancy.datasource3.password=****
spring.multitenancy.datasource3.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update

DataSourceBasedMultiTenantConnectionProviderImpl.java

@Component
public class DataSourceBasedMultiTenantConnectionProviderImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {

private static final long serialVersionUID = 8168907057647334460L;
private static final String DEFAULT_TENANT_ID = "tenant_1";

@Autowired
private DataSource dataSource1;

@Autowired
private DataSource dataSource2;

@Autowired
private DataSource dataSource3;

private Map<String, DataSource> map;

@PostConstruct
public void load() {
map = new HashMap<>();
map.put("tenant_1", dataSource1);
map.put("tenant_2", dataSource2);
map.put("tenant_3", dataSource3);
}

@Override
protected DataSource selectAnyDataSource() {
return map.get(DEFAULT_TENANT_ID);
}

@Override
protected DataSource selectDataSource(String tenantIdentifier) {
return map.get(tenantIdentifier);
}
}

Multi-Tenancy 属性.java

@ConfigurationProperties("spring.multitenancy")
public class MultitenancyProperties {

@NestedConfigurationProperty
private DataSourceProperties datasource1;

@NestedConfigurationProperty
private DataSourceProperties datasource2;

@NestedConfigurationProperty
private DataSourceProperties datasource3;

public DataSourceProperties getDatasource1() {
return datasource1;
}

public void setDatasource1(DataSourceProperties datasource1) {
this.datasource1 = datasource1;
}

public DataSourceProperties getDatasource2() {
return datasource2;
}

public void setDatasource2(DataSourceProperties datasource2) {
this.datasource2 = datasource2;
}

public DataSourceProperties getDatasource3() {
return datasource3;
}

public void setDatasource3(DataSourceProperties datasource3) {
this.datasource3 = datasource3;
}
}

MultiTenancyJpaConfiguration.java

@Configuration
@EnableConfigurationProperties(JpaProperties.class)
public class MultiTenancyJpaConfiguration {

@Autowired
private DataSource dataSource;

@Autowired
private JpaProperties jpaProperties;

@Autowired
private MultiTenantConnectionProvider multiTenantConnectionProvider;

@Autowired
private CurrentTenantIdentifierResolver currentTenantIdentifierResolver;

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
Map<String, Object> hibernateProps = new LinkedHashMap<>();
hibernateProps.putAll(jpaProperties.getHibernateProperties(dataSource));

hibernateProps.put(Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
hibernateProps.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProvider);
hibernateProps.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolver);
hibernateProps.put(Environment.DIALECT, "org.hibernate.dialect.MySQLDialect");

return builder.dataSource(dataSource).packages(HotelEntity.class.getPackage().getName()).properties(hibernateProps).jta(false).build();
}
}

应用程序启动器

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(MultitenancyProperties.class)
public class Application {

public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}

当我运行启动应用程序时,所有表都仅在第一个数据源中创建。
1)如何在应用启动时在所有数据源中创建表?
2) 如何查看每个数据源打开/关闭的连接?
3) 有没有更好的方法来使用 Spring Boot 配置 Multi-Tenancy 应用程序以获得更好的性能?

最佳答案

正如@Alex 所说,您需要不同的 EntityManagers、TransactionManager 和 Datasources。这是我的做法

@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "dataSource1EntityManagerFactory",
transactionManagerRef = "dataSource1TransactionManager",
basePackageClasses = dataSource1Repository.class)
public class DataSource1Config extends SqlConfig{// Put all common code in base class SqlConfig. If not remove it

@Bean
@Primary
public DataSource dataSource1() {
//create dataSource using MultitenancyProperties::getDataSource1
}

@Primary
@Bean(name = "dataSource1TransactionManager")
PlatformTransactionManager dataSource1TransactionManager(EntityManagerFactory dataSource1EntityManagerFactory) {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(dataSource1EntityManagerFactory);
return txManager;
}

@Primary
@Bean(name = "dataSource1EntityManagerFactory")
LocalContainerEntityManagerFactoryBean dataSource1EntityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource1());
em.setPackagesToScan(dataSource1Repository.class.getPackage().getName(), dataSource1ModelClass.class.getPackage().getName());
em.setPersistenceUnitName("dataSource1Db");

HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setGenerateDdl(false);
em.setJpaVendorAdapter(vendorAdapter);
return em;
}
}

您可以像这样创建另外两个类。请记住仅在数据源、事务管理器和实体管理器的一个实例上使用 @Primary(不管是哪一个)。再提醒一句,请确保存储库类位于所有三个数据库的不同包中。

关于java - 在 Spring Boot 应用程序的多个数据库中未创建表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43122329/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com