我们的应用程序允许我们的客户拥有多个数据库,所有数据库都在一个数据库服务器实例上运行。
例如,数据库可能是dbcommon,dbLive,dbStaging,dbUAT,dbDev,dbSandbox。公共数据库和生产数据库始终存在,但其他数据库是可选的(并且没有限制)。在dbcommon中有一个表告诉我们所有的数据库....所以我需要启动它。共同的表与其他表不同,其他表都具有相同的模式(订户数据)
使用Hibernate,我如何动态创建/使用Live或Staging(或任何其他)的连接?如果有帮助,我正在使用Spring。
我遇到了建议在配置中创建不同连接的答案,但由于订阅者数据库的数量可能不同(每次安装,而不是在应用程序运行时),这对我来说不是一个选项。
答案 0 :(得分:1)
正如我在发布此问题后发现的那样,并且正如用户manish所建议的那样,Hibernate的Multi Tenancy支持(使用Database MultiTenancyStrategy)对我有用。我不得不使用各种资源(下面列出)拼凑出一个解决方案。
http://www.ticnfae.co.uk/blog/2014/07/16/hibernate-multi-tenancy-with-spring/
Setting up a MultiTenantConnectionProvider using Hibernate 4.2 and Spring 3.1.1
我仍然在寻找一种能够在租户数据库的同时引用公共(共享)数据库的方法......并且在完成后会尝试将其添加到此答案中。
答案 1 :(得分:0)
我能看到的最简单的方法是在Spring中通过配置文件管理所有内容。
我使用application.yml完成了这个。我也使用了Hikari连接池,但这并没有太多影响配置。
这是一个application.yml的示例,其中列出了3个配置文件,并且我已将其中两个配置文件作为示例。
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;
}
}
实体和存储库是正常定义的,那里没什么特别的。数据库将根据我告诉它运行的任何配置文件切换连接。
我只是将application.yml中的active
个人资料转换为我需要的个人资料。
安全注意事项:定义生产配置文件,不要将生产作为默认配置文件。