我们在Hibernate中需要多个模式。
在我们的项目中,我们需要根据用户名和密码连接到多个模式。但是如何在Hibernate中配置多个模式?
如果有办法,请告诉我。
答案 0 :(得分:3)
您可以在为实体定义表时按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的。
答案 1 :(得分:2)
感谢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
来隐藏用户/密码凭据。
答案 2 :(得分:0)
与弗拉德·米哈尔恰(Vlad Mihalcea)的答案相反,该答案解释了多个数据库租户的连接提供者,模式的方法在this url
中进行了解释。