如何使用 Hibernate 配置多个模式
How to configure multiple schemas with Hibernate
我们需要在 Hibernate 中使用多个模式。
在我们的项目中,我们需要根据用户名和密码连接到多个模式。但是如何在 Hibernate 中配置多个模式?
如果有办法请告诉我。
您可以在为您的实体定义 table 时通过 schema
元素指定它。
@Table(name="TABLE_NAME", schema="SCHEMA_NAME")
否则,您可以使用单独的 EntityManager
指向各自的模式,然后使用相同的实体,因为它们的结构相似。
编辑: 您可以为每个模式创建单独的配置文件,然后从中构建 SessionFactory
,下面是一些伪代码。
SessionFactory sf_1 = new Configuration().configure("schema1config.cfg.xml").buildSessionFactory();
SessionFactory sf_2 = new Configuration().configure("schema2config.cfg.xml").buildSessionFactory();
session_1 = sf_1.openSession(); //-- Similarly for other
您可以参考 this link 以了解映射多个模式的更多详细信息,但它不是特定于休眠的。
多亏了 Hibernate Multitenancy support,您可以按如下方式轻松做到这一点:
下面的例子可以在Hibernate ORM documentation folder.
中找到
每个模式都可以是一个租户,所以你只需要向 Hibernate 提供一个租户标识符 Session
,Hibernate 就会知道要连接到什么数据库模式:
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
实现:
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 );
}
}
你可以初始化如下:
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
定义如下:
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
:
中的不同租户和架构
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
来隐藏 user/password 凭据。
与 Vlad Mihalcea 的回答相反,该回答解释了多个数据库租户的连接提供程序,模式的方法在 this url
中解释如下
我们需要在 Hibernate 中使用多个模式。
在我们的项目中,我们需要根据用户名和密码连接到多个模式。但是如何在 Hibernate 中配置多个模式?
如果有办法请告诉我。
您可以在为您的实体定义 table 时通过 schema
元素指定它。
@Table(name="TABLE_NAME", schema="SCHEMA_NAME")
否则,您可以使用单独的 EntityManager
指向各自的模式,然后使用相同的实体,因为它们的结构相似。
编辑: 您可以为每个模式创建单独的配置文件,然后从中构建 SessionFactory
,下面是一些伪代码。
SessionFactory sf_1 = new Configuration().configure("schema1config.cfg.xml").buildSessionFactory();
SessionFactory sf_2 = new Configuration().configure("schema2config.cfg.xml").buildSessionFactory();
session_1 = sf_1.openSession(); //-- Similarly for other
您可以参考 this link 以了解映射多个模式的更多详细信息,但它不是特定于休眠的。
多亏了 Hibernate Multitenancy support,您可以按如下方式轻松做到这一点:
下面的例子可以在Hibernate ORM documentation folder.
中找到每个模式都可以是一个租户,所以你只需要向 Hibernate 提供一个租户标识符 Session
,Hibernate 就会知道要连接到什么数据库模式:
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
实现:
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 );
}
}
你可以初始化如下:
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
定义如下:
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
:
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
来隐藏 user/password 凭据。
与 Vlad Mihalcea 的回答相反,该回答解释了多个数据库租户的连接提供程序,模式的方法在 this url
中解释如下