如何使用Hibernate配置多个架构 [英] How to configure multiple schemas with Hibernate
问题描述
我们对Hibernate中的多个模式有要求.
We have got a requirement for multiple schemas in Hibernate.
在我们的项目中,我们需要基于用户名和密码连接到多个架构.但是如何在Hibernate中配置多个架构?
In our project, we need to connect to multiple schemas based on the username and password. But how to configure multiple schemas in Hibernate?
请告诉我是否有办法.
推荐答案
感谢休眠多租户支持,您可以按以下步骤轻松地做到这一点:
Thanks to Hibernate Multitenancy support, you can easily do that as follows:
以下示例可在休眠ORM文档文件夹.
每个模式都可以是一个租户,因此您只需向Hibernate Session
提供一个租户标识符,Hibernate就会知道要连接到哪个数据库模式:
Each schema can be a tenant, so you only need to provide a tenant identifier to the Hibernate Session
, and Hibernate will know what database schema to connect to:
private void doInSession(String tenant, Consumer<Session> function) {
Session session = null;
Transaction txn = null;
try {
session = sessionFactory
.withOptions()
.tenantIdentifier( tenant )
.openSession();
txn = session.getTransaction();
txn.begin();
function.accept(session);
txn.commit();
} catch (Throwable e) {
if ( txn != null ) txn.rollback();
throw e;
} finally {
if (session != null) {
session.close();
}
}
}
您还需要提供一个 MultiTenantConnectionProvider
实现:
You need to provide a MultiTenantConnectionProvider
implementation as well:
public class ConfigurableMultiTenantConnectionProvider
extends AbstractMultiTenantConnectionProvider {
private final Map<String, ConnectionProvider> connectionProviderMap =
new HashMap<>( );
public ConfigurableMultiTenantConnectionProvider(
Map<String, ConnectionProvider> connectionProviderMap) {
this.connectionProviderMap.putAll( connectionProviderMap );
}
@Override
protected ConnectionProvider getAnyConnectionProvider() {
return connectionProviderMap.values().iterator().next();
}
@Override
protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) {
return connectionProviderMap.get( tenantIdentifier );
}
}
您可以按如下所示对其进行初始化:
And you can initialize it as follows:
private void init() {
registerConnectionProvider( FRONT_END_TENANT );
registerConnectionProvider( BACK_END_TENANT );
Map<String, Object> settings = new HashMap<>( );
settings.put( AvailableSettings.MULTI_TENANT, multiTenancyStrategy() );
settings.put( AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER,
new ConfigurableMultiTenantConnectionProvider( connectionProviderMap ) );
sessionFactory = sessionFactory(settings);
}
protected void registerConnectionProvider(String tenantIdentifier) {
Properties properties = properties();
properties.put( Environment.URL,
tenantUrl(properties.getProperty( Environment.URL ), tenantIdentifier) );
DriverManagerConnectionProviderImpl connectionProvider =
new DriverManagerConnectionProviderImpl();
connectionProvider.configure( properties );
connectionProviderMap.put( tenantIdentifier, connectionProvider );
}
由于该示例使用H2,因此 tenantUrl
的定义如下:
Since this example uses H2, the tenantUrl
is defined like this:
public static final String SCHEMA_TOKEN = ";INIT=CREATE SCHEMA IF NOT EXISTS %1$s\\;SET SCHEMA %1$s";
@Override
protected String tenantUrl(String originalUrl, String tenantIdentifier) {
return originalUrl + String.format( SCHEMA_TOKEN, tenantIdentifier );
}
现在,您可以只使用来自同一 SessionFactory
的单独的租户和架构:
Now you can just use separate tenants and schemas from the same SessionFactory
:
doInSession( FRONT_END_TENANT, session -> {
Person person = new Person( );
person.setId( 1L );
person.setName( "John Doe" );
session.persist( person );
} );
doInSession( BACK_END_TENANT, session -> {
Person person = new Person( );
person.setId( 1L );
person.setName( "John Doe" );
session.persist( person );
} );
由于 MultiTenantConnectionProvider
的行为与其他任何 ConnectionProvider
相同,因此您可以将每个租户配置为使用单独的 DataSource
,这会隐藏用户/密码凭据
Since the MultiTenantConnectionProvider
acts like any other ConnectionProvider
, you can configure each tenant to use a separate DataSource
which hides the user/password credentials.
这篇关于如何使用Hibernate配置多个架构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!