簡體   English   中英

在Spring啟動應用程序中未在多個數據庫中創建表

[英]Tables not getting created in multiple databases in spring boot application

我正在開發spring boot多租賃應用程序。 我已經配置了多個數據源,如下所示:

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);
    }
}

MultitenancyProperties.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)是否有更好的方法使用彈簧啟動配置多租賃應用程序以獲得更好的性能?

正如@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上使用@Primary (無關緊要)。 另一個需要注意的是,確保Repository類位於所有三個數據庫的不同包中。

您需要2個不同的持久性工廠,而不是一個,每個工廠應為不同的數據源生成不同的EntityManagers。 此外,每個實體映射都應標記為僅與一個實體管理器一起使用。 請在此處查看完整解

http://www.baeldung.com/spring-data-jpa-multiple-databases

嘗試添加以下屬性:

spring.jpa.generate-ddl=true

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM