2016-06-23 188 views
0

我得到了一个要求,每个公司都有独立的数据库和相同的模式,未来的新公司可能会被添加到相同的模式结构中。我必须基于用户来连接他们的公司模式登录。所以我必须在每次用户登录时连接单独的数据库。我将使用Spring数据JPA来处理连接。只有我将在属性文件中配置新的模式凭证。是否有任何方法可以添加使用动态数据库模式相同的模型类。所有应该只在运行时发生。spring data jpa(hibernate + spring + jpa)

+1

难道你不能为每个公司有不同的模式,都在一个数据库中吗?我认为这会容易得多 –

+0

是的,这可能是可能的。但我的问题是连接不同的架构与弹簧数据jpa。我将如何实现这一点,由于架构可能会动态添加。弹簧需要在配置时间只。 –

回答

1

听起来像你问的是多租户支持。您可以创建一个LocalContainerEntityManagerFactoryBean是这样的:

@Bean 
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
     DataSource dataSource, 
     MultiTenantConnectionProvider multiTenantConnectionProvider, 
     CurrentTenantIdentifierResolver tenantIdentifierResolver) { 

    LocalContainerEntityManagerFactoryBean emfBean = new LocalContainerEntityManagerFactoryBean(); 
    emfBean.setDataSource(dataSource); 
    emfBean.setPackagesToScan(Application.class.getPackage().getName()); 
    emfBean.setJpaVendorAdapter(jpaVendorAdapter()); 

    Map<String, Object> jpaProperties = new HashMap<>(); 
    jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect"); 

    // Improved naming strategy deprecated as of hibernate 5.0 
    // jpaProperties.put("hibernate.ejb.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy"); 
    jpaProperties.put("hibernate.implicit_naming_strategy", "org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl"); 
    jpaProperties.put("hibernate.physical_naming_strategy", "com.example.config.HibernateLegacyImprovedNamingStrategy"); 

    jpaProperties.put("hibernate.show_sql", "true"); 
    jpaProperties.put("hibernate.format_sql", "true"); 
    jpaProperties.put(org.hibernate.cfg.Environment.MULTI_TENANT, MultiTenancyStrategy.SCHEMA); 
    jpaProperties.put(org.hibernate.cfg.Environment.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProvider); 
    jpaProperties.put(org.hibernate.cfg.Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, tenantIdentifierResolver); 
    emfBean.setJpaPropertyMap(jpaProperties); 
    return emfBean; 
} 

,并提供MultiTenantConnectionProviderCurrentTenantIdentifierResolver

实现作为一个例子,对于模式的租赁,在CurrentTenantIdentifierResolver可以查找从会话当前用户确定什么模式来使用。

MultiTenantConnectionProvider可能会在返回连接使用(并在返回时重置)之前使用类似SELECT set_schema_to(?)的命令更改连接。

@Override 
public Connection getConnection(String tenantIdentifier) throws SQLException { 
    final Connection connection = getAnyConnection(); 
    setSchemaTo(connection, tenantIdentifier); 
    return connection; 
} 

您需要阅读有关多租户的信息,并了解您希望使用哪种实现方式。

+0

嗨格伦谢谢,我认为这将解决我的问题。我会试一试。 –