如何使用Hibernate配置多个架构 [英] How to configure multiple schemas with Hibernate

查看:74
本文介绍了如何使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆