如何在单个服务器上使用Hibernate与多个数据库

4

我们的应用程序允许客户在一个数据库服务器实例上运行多个数据库。

例如,这些数据库可以是dbcommon、dbLive、dbStaging、dbUAT、dbDev和dbSandbox。通用数据库和生产数据库始终存在,但其他数据库是可选的(且没有限制)。在dbcommon中有一张表告诉我们所有的数据库......所以我需要从那里开始。通用数据库中的表与其他数据库中的表不同,并且其他数据库都具有相同的模式(订阅者数据)。

使用Hibernate,我如何动态创建/使用连接到Live或Staging(或其他任何数据库)?如果有帮助的话,我正在使用Spring。

我发现一些答案建议在配置中创建不同的连接,但由于订阅者数据库的数量可能会因每次安装而异(而不是在应用程序运行时),对我来说这不是一个选项。


我必须在我的应用程序中完成这个任务。我正在使用Spring和repositories进行管理。我可以这样解释。 - kevingreen
对我来说,Spring 处理连接,并通过配置文件进行运行。配置文件决定了测试、阶段、生产等环境。我有三个数据库需要随时连接。我必须切换环境,并使这三个数据库指向其他位置。我可以向您展示我的配置,但如果您没有使用 Spring,可能不是很有帮助。它实现了 JPA 覆盖 Hibernate,可能会引出一些想法。 - kevingreen
我们也使用存储库模式。自从发布问题以来,我已经找到了Hibernate的多租户文档页面...我正在看它是否也适用。 - Adam Erstelle
我最终将会使用Spring JPA和Hibernate,对我来说那很好! - Adam Erstelle
好的,我需要几分钟来编写它。 - kevingreen
您可以将每个数据库视为单独的租户(客户)。然后使用Hibernate中的多租户支持,将各个查询指向正确的数据库。 - manish
2个回答

1
正如我在发布这个问题后发现的,正如用户manish建议的那样,Hibernate的多租户支持(使用数据库MultiTenancyStrategy)适合我。我不得不使用各种资源(下面列出)来拼凑解决方案。

http://www.ticnfae.co.uk/blog/2014/07/16/hibernate-multi-tenancy-with-spring/

使用Hibernate 4.2和Spring 3.1.1设置MultiTenantConnectionProvider

Spring + Hibernate的多租户支持:“SessionFactory已配置为多租户,但未指定租户标识符”

我仍在寻找一种同时引用公共(共享)数据库和租户数据库的方法……完成后将尝试将其添加到此答案中。


1
你可以使用两个 SessionFactory。一个用于常规数据库,使用默认的 Hibernate 基础设施,另一个用于其他数据库,使用多租户支持。 - manish

-1
我认为最简单的方法是通过Spring中的配置文件来管理所有内容。
我使用application.yml实现了这一点。我还使用了Hikari连接池,但这并不会对配置产生太大影响。
以下是一个包含3个配置文件的application.yml示例,并且我定义了其中两个作为示例。
spring:
  profiles:
    include: dev,test,production
    active: dev
---
spring:
  profiles: dev
oms:
  omsDataSource:
    driverClassName: com.informix.jdbc.IfxDriver
    jdbcUrl: jdbc:informix-sqli://devdb:9000/hol:INFORMIXSERVER=m_tcp_1;client_deve=en_US.8859-1;db_deve=en_US.8859-1;LOBCACHE=-1
    password: oms
    username: oms
    connectionTestQuery: select count(*) from systables
    maximumPoolSize: 5

---
spring:
  profiles: test
oms:
  omsDataSource:
    driverClassName: com.informix.jdbc.IfxDriver
    jdbcUrl: jdbc:informix-sqli://testdb:9000/hol:INFORMIXSERVER=m_tcp_1;client_deve=en_US.8859-1;db_deve=en_US.8859-1;LOBCACHE=-1
    password: oms
    username: oms
    connectionTestQuery: select count(*) from systables
    maximumPoolSize: 5

在我的数据库配置类中,我设置了JPA存储库,并告诉它使用哪个entityManager。我还设置了配置属性以从application.yml中提取。这意味着它将根据应用程序在启动时使用的配置文件替换详细信息。
@EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryOms",
        transactionManagerRef = "transactionManagerOms",
        basePackages= "persistence.oms")
@Configuration
@ConfigurationProperties(prefix = "oms.omsDataSource")
public class omsDbConfig extends HikariConfig {

//This will automatically fill in the required fields from the application.yml. 
    @Bean
    public HikariDataSource orcaDataSource() throws SQLException {
        return new HikariDataSource(this);
    }

//I use that datasource to define my entityMangerFactory
@Bean(name = "entityManagerFactoryOms")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryOrca() throws SQLException {
        JpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        Properties props = new Properties();
        props.setProperty("hibernate.dialect","org.hibernate.dialect.InformixDialect");
        LocalContainerEntityManagerFactoryBean emfb =
                new LocalContainerEntityManagerFactoryBean();
        emfb.setDataSource(orcaDataSource());
        emfb.setPackagesToScan("persistence.oms");
        emfb.setJpaProperties(props);
        emfb.setJpaVendorAdapter(adapter);
        return emfb;
    }

    }

实体和存储库的定义通常是正常的,没有什么特别之处。DB将根据我告诉它运行的任何配置文件切换连接。

我只需在application.yml中切换active配置文件到我需要的任何一个。

安全注意事项:定义一个生产配置文件,不要将生产设置为默认配置文件。


我们有数百个安装,我认为这对我们不起作用(在本地管理每个客户端的安装并更改它,以便应用程序可以在安装时为他们工作)。 - Adam Erstelle
以编程方式构建 DataSource 和实体管理器。安装时仍需要设置一个 DataSource,指向其中包含数据库名称的表格。该初始 DataSource 可以在 application.yml 文件中设置。 - kevingreen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接