gdr*_*drt 10 java spring hibernate multi-tenant
我实现了Hibernate的多租户数据库架构,根据租户选择特定的数据库连接.我正在使用Spring 4.3和Hibernate 5.2.
当租户使用相同的RDBMS时,一切都很好,但是当他们不同时,我必须动态更改hibernate属性中的方言设置,我不知道如何.
我的hibernate属性在dispatcher-servlet.xml中:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.example"/>
<mvc:annotation-driven/>
<context:property-placeholder location="classpath:application.properties"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" >
<property name="packagesToScan">
<list>
<value>com.example.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<!--<prop key="hibernate.dialect">${hibernate.dialect}</prop>-->
<prop key="hibernate.show_sql">${hibernate.show_sql:false}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql:false}</prop>
<prop key="hibernate.multiTenancy">DATABASE</prop>
<prop key="hibernate.tenant_identifier_resolver">com.example.multitenancy.CurrentTenantIdentifierResolverImpl</prop>
<prop key="hibernate.multi_tenant_connection_provider">com.example.multitenancy.MultiTenantConnectionProviderImpl</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
Run Code Online (Sandbox Code Playgroud)
下面是Hibernate的CurrentTenantIdentifierResolver的实现:
public class CurrentTenantIdentifierResolverImpl implements CurrentTenantIdentifierResolver {
@Override
public String resolveCurrentTenantIdentifier() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return Helper.getTenantFromAuthentication(authentication);
}
@Override
public boolean validateExistingCurrentSessions() {
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
和AbstractDataSourceBasedMultiTenantConnectionProviderImpl的实现:
public class MultiTenantConnectionProviderImpl extends AbstractDataSourceBasedMultiTenantConnectionProviderImpl {
@Override
protected DataSource selectAnyDataSource() {
return getDataSource("tenantId1");
}
@Override
protected DataSource selectDataSource(String tenantIdentifier) {
return getDataSource(tenantIdentifier);
}
private DataSource getDataSource(String prefix) {
Properties properties = new Properties();
try {
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("application.properties"));
} catch (IOException e) {
throw new RuntimeException();
}
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(properties.getProperty(prefix + ".driverClassName"));
dataSource.setUrl(properties.getProperty(prefix + ".url"));
dataSource.setUsername(properties.getProperty(prefix + ".username"));
dataSource.setPassword(properties.getProperty(prefix + ".password"));
return dataSource;
}
}
Run Code Online (Sandbox Code Playgroud)
在application.properties文件看起来是这样的:
tenantId1.driverClassName = org.postgresql.Driver
tenantId1.url = <...>
tenantId1.username = <...>
tenantId1.password = <...>
tenantId2.driverClassName = com.mysql.jdbc.Driver
tenantId2.url = <...>
tenantId2.username = <...>
tenantId2.password = <...>
Run Code Online (Sandbox Code Playgroud)
有没有办法动态改变hibernate方言?
您无法使用单个休眠配置文件来实现。您需要为每个数据库拥有不同的配置文件。
例如,您有两个数据库MySql和Oracle:
配置mysql数据库
hibernate-mysql.cfg.xml
Run Code Online (Sandbox Code Playgroud)
配置oracle数据库
hibernate-oracle.cfg.xml
Run Code Online (Sandbox Code Playgroud)
创建两个不同的会话,代码应该像这样。
private static SessionFactory sessionAnnotationFactory;
sessionAnnotationFactory = new Configuration().configure("hibernate-mysql.cfg.xml").buildSessionFactory();
Session MySqlSession = sessionAnnotationFactory.openSession();
Run Code Online (Sandbox Code Playgroud)
对于Oracle数据库配置
sessionAnnotationFactory = new Configuration().configure("hibernate-oracle.cfg.xml").buildSessionFactory();
Session OracleSession = sessionAnnotationFactory.openSession()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3160 次 |
| 最近记录: |