Hibernate动态改变多个连接

时间:2016-11-18 22:09:09

标签: java database postgresql hibernate

我知道关于这种情况也有类似的问题,但是我发现它们都不符合我的情况,我希望有一个不会影响性能的解决方案。我必须与不同的数据库(所有postgresql)建立多个连接,问题是数据库可能很多,因为它们不断被创建。

目前我只有一个已知的数据库,用于存储来自其他数据库的连接字符串。这些数据库可以是1,2,5,10或N,棘手的部分是,从我的角度来看,我永远不会知道他们将会有多少以及他们的位置和凭据是什么(都存储在我的中央数据库中) 。该用例的工作方式是,为了在这些数据库之一上进行操作,我必须首先从中央数据库中获取所需数据库的位置,然后执行操作。

目前,我已经能够通过单一的SessionFactory执行操作,但即使是简单的选择/更新,操作也太慢了,我担心的是,当发出多个请求时,我们可能会从Hibernate获得内存异常。

关于这种情况的最佳方法的任何想法?

3 个答案:

答案 0 :(得分:1)

我们有类似的事情: 1..N数据库作为不同的客户。每个客户都有相同的架构,因此我们只有1个实体管理器。 所以你需要通过spi 2实现类提供hibernete,并通过属性提供handen:

<强> hibernate.multi_tenant_connection_provider org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider

和 的 hibernate.tenant_identifier_resolver org.hibernate.context.spi.CurrentTenantIdentifierResolver

&#34; hibernate.multiTenancy&#34;,&#34; SCHEMA&#34;

以下是如何使用spring framework

执行此操作的示例
  LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
    emf.setJpaVendorAdapter(jpaVendorAdapter());
    emf.setPersistenceUnitName("security");
    Properties hibernateProperties = new Properties();
    hibernateProperties.put("hibernate.cache.use_second_level_cache", "true");
    hibernateProperties.put("hibernate.multiTenancy", "SCHEMA");
    // do not load all metadata from standard db speadup startup
    hibernateProperties.put("hibernate.temp.use_jdbc_metadata_defaults", "false");
    hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQL9Dialect");
    hibernateProperties.put("hibernate.multi_tenant_connection_provider", multiTenantConnectionProvider());
    hibernateProperties.put("hibernate.tenant_identifier_resolver", currentTenantIdentifierResolver(tenant));
    hibernateProperties.put("hibernate.show_sql", true);
    emf.setJpaProperties(hibernateProperties);
    emf.setJpaDialect(new HibernateJpaDialect());
    LOG.info("LocalContainerEntityManagerFactoryBean bean created");
    return emf;

答案 1 :(得分:0)

根据我的经验,我使用了来自单个数据库的许多模式。 Hibernate需要为每个单独的模式以及每个数据库创建许多EntityManagerFactory。

每个模式或您正在使用的每个数据库都需要一个EntityManagerFactory。
而且你知道EntityManagerFactory在资源和时间方面非常昂贵。
之后获得单个EntityManager非常便宜。

因此,在您的情况下,您必须创建一个N EntityManagerFactory,其中一个用于每个不同的数据库或来自相同数据库的不同模式。

由于创建EntityManagerFactory的成本很高,因此必须在必要时和必要时创建它们,并且您知道必须等待将近30秒或更长时间才能获得所有人。

为了避免内存不足异常,您可以尝试进行测试,以创建从1到N的最大EntityManagerFactory数,并查看您的资源是否可以支持此功能。

如果你看到当你到达一个X号码并且因为这总是系统崩溃而烦恼时,那么你可以将EntityManagerFactory的同时数限制为这个X限制数。

尝试让我知道您的结果,或者您是否需要一些代码示例

答案 2 :(得分:0)

我正以一种不同的方式思考这个问题。

根据我的理解

  

您的要求是从不同的数据库中获取数据   你在发展的时候不知道。

所以为什么你试图将所有这些负载放在hibernate上来管理与这么多数据库的连接。

你很清楚主数据库是什么。

让master数据库做其余事情。

  

您应该只与master数据库通信以及获取所有负担   其余数据库中的数据应保存在主数据库中。

     

为master数据库中的不同数据库创建DBLink。

并在master数据库中维护所需的元数据。

  

每当您需要从任何新添加的数据库中获取数据时,   刚刚从master数据库询问。

使用DBLinks可以解决的问题

  • 您不必在任何表格中公开(不同数据库的)数据库凭据
  • Hibernate将保持轻量化
  • 您的Java代码将保持清洁
  • 任何数据库(结构,凭据)中所做的任何更改都会立即反映出来(在数据库中进行任何此类更改后,您需要重新启动应用程序)

A reference for DBLink in postgres