gpt4 book ai didi

java - Spring Multi-Tenancy : Add a data source to MultiTenantConnectionProvider dynamically when a user is added

转载 作者:行者123 更新时间:2023-11-30 10:35:13 26 4
gpt4 key购买 nike

我有一个场景,其中用户注册并为他们创建一个新数据库。注册过程完成后,需要将此数据库添加到 MultiTenantConnectionProvider(连接池)。一切正常,但无法将数据源动态添加到 MultiTenantConnectionProvider。

Multi-Tenancy 的 Hibernate 配置:

       <property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.multiTenancy">DATABASE</prop>
<prop key="hibernate.tenant_identifier_resolver">com.company.multitenancy.MyCurrentTenantIdentifierResolverImpl
</prop>
<prop key="hibernate.multi_tenant_connection_provider">com.company.multitenancy.MyMultiTenantConnectionProvider
</prop>
</props>
</property>

MyMultiTenantConnectionProvider 的代码:

package com.company.multitenancy;

import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import com.termbreak.constant.ConstantStrings;

public class MyMultiTenantConnectionProvider extends
AbstractMultiTenantConnectionProvider {
private static final long serialVersionUID = -8669630427906544663L;
private HashMap<String, ConnectionProviderImpl> connProviderMap = new HashMap<String, ConnectionProviderImpl>();

public MyMultiTenantConnectionProvider() {
List<String> providerNames = new ArrayList<String>();
providerNames.add(ConstantStrings.DEFAULT_TENANT_ID);
try {
String sqlUrl = "jdbc:mysql://localhost:3306/"+ConstantStrings.DEFAULT_TENANT_ID;
Class.forName("com.mysql.jdbc.Driver");
java.sql.Connection conn = DriverManager.getConnection(sqlUrl,
"root", "root");
Statement st = conn.createStatement();
ResultSet rs = st
.executeQuery("select DISTINCT TENANT_ID from User");
while (rs.next()) {
String tenantId = rs.getString(1);
providerNames.add(tenantId);
}
conn.close();
} catch (Exception e) {
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
}
for (String providerName : providerNames) {
connProviderMap.put(providerName, new ConnectionProviderImpl(
providerName));
}
}

public ConnectionProvider getAnyConnectionProvider() {
System.out
.println("inside MultiTenantConnectionProvider::getAnyConnectionProvider");
return connProviderMap.get(ConstantStrings.DEFAULT_TENANT_ID);
}

public ConnectionProvider selectConnectionProvider(String tenantId) {
ConnectionProvider connectionProvider = connProviderMap.get(tenantId);
if (connectionProvider == null)
connectionProvider = new ConnectionProviderImpl(ConstantStrings.DEFAULT_TENANT_ID);
return connectionProvider;
}
}

MyCurrentTenantIdResolver 的代码:

package com.company.multitenancy;

import org.hibernate.context.spi.CurrentTenantIdentifierResolver;

import com.termbreak.constant.ConstantStrings;

public class MyCurrentTenantIdentifierResolverImpl implements
CurrentTenantIdentifierResolver {
public ThreadLocal<String> _tenantIdentifier = new ThreadLocal<String>();
public String DEFAULT_TENANT_ID = ConstantStrings.DEFAULT_TENANT_ID;

public String resolveCurrentTenantIdentifier() {
System.out.println("from inside resolveCurrentTenantIdentifier....");
String tenantId = _tenantIdentifier.get();
if (tenantId == null)
tenantId = DEFAULT_TENANT_ID;
System.out.println("threadlocal tenant id =" + tenantId);
return tenantId;
}

public boolean validateExistingCurrentSessions() {
return true;
}

}

MyConnectionProviderImpl 的代码:

package com.company.multitenancy;

import java.sql.Connection;
import java.sql.SQLException;

import org.apache.commons.dbcp2.BasicDataSource;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;

public class ConnectionProviderImpl implements ConnectionProvider {
private static final long serialVersionUID = -8926112316994338537L;
private BasicDataSource basicDataSource;

public ConnectionProviderImpl(String database){
//this should be read from properties file
basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
basicDataSource.setUrl("jdbc:mysql://localhost:3306/"+database);
basicDataSource.setUsername("root");
basicDataSource.setPassword("root");
basicDataSource.setInitialSize(2);
}
public boolean isUnwrappableAs(Class arg0) {
return false;
}
public Object unwrap(Class arg0) {
return null;
}
public void closeConnection(Connection arg0) throws SQLException {
arg0.close();
}
public Connection getConnection() throws SQLException {
return basicDataSource.getConnection();
}
public boolean supportsAggressiveRelease() {
return false;
}
}

要连接到我正在使用的特定租户:

sessionFactory.withOptions().tenantIdentifier(tenantId).openSession();

最佳答案

除了 ConnectionProviderImpl 的实现之外,您的配置似乎是正确的。在此实现中,您需要为 hibernate 提供租户标识符。您需要实现 AbstractDataSourceBasedMultiTenantConnectionProviderImpl 并根据您使用的 Hibernate 版本覆盖 getConnection() 或 selectDataSource() 。我建议您遵循 Hibernate 用户指南 https://docs.jboss.org/hibernate/orm/4.3/devguide/en-US/html/ch16.html示例 16.3 和这篇文章 http://www.ticnfae.co.uk/blog/2014/07/16/hibernate-multi-tenancy-with-spring/ .

关于java - Spring Multi-Tenancy : Add a data source to MultiTenantConnectionProvider dynamically when a user is added,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41311580/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com