我有,其中,用戶註冊一個新的數據庫,爲他們創造了一個場景。註冊過程完成後,需要將該數據庫添加到MultiTenantConnectionProvider(連接池)中。一切正常,但無法將數據源動態添加到MultiTenantConnectionProvider。春季多租戶:數據源添加到MultiTenantConnectionProvider動態當用戶添加
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();
感謝您的快速回復,每一件事情正在完善與此代碼,當用戶註冊爲該用戶創建一個新的數據庫,並生成一個新的租戶ID我需要添加我面臨的,現在唯一的問題是這個租戶ID到連接池,我無法。任何指針將幫助 –
而不是直接實現的ConnectionProvider,您可以通過擴展AbstractDataSourceBasedMultiTenantConnectionProviderImpl試圖重寫selectDataSource()。 MyCurrentTenantIdentifierResolverImpl#resolveCurrentTenantIdentifier()返回承租人標識符。此租戶標識符在AbstractDataSourceBasedMultiTenantConnectionProviderImpl#selectDataSource(字符串tenantIdentifier)使用。 –