【问题标题】:How to use C3P0 in a spring boot hibernate multi tenant application to manage connection pool?如何在 Spring Boot Hibernate 多租户应用程序中使用 C3P0 来管理连接池?
【发布时间】:2019-10-13 17:16:49
【问题描述】:

我正在尝试使用 hibernate 的 MultiTenantConnectionProvider 和 CurrentTenantIdentifierResolver 实现一个多租户应用程序。我不确定池是如何由休眠管理的,以及将其留给休眠是否是一个好习惯。我可以在这个多租户应用程序中使用 C3P0。

这是我的初始代码:

@Bean(name = "dataSources" )
public Map<String, DataSource> dataSources() {
    Map<String, DataSource> result = new HashMap<>();
    for (DataSourceProperties dsProperties : this.multiTenantProperties.getDataSources()) {
        DataSourceBuilder factory = DataSourceBuilder
            .create()
            .url(dsProperties.getUrl())
            .username(dsProperties.getUsername())
            .password(dsProperties.getPassword())
            .driverClassName(dsProperties.getDriverClassName());
        result.put(dsProperties.getTenantId(), factory.build());
    }
    return result;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(MultiTenantConnectionProvider DataSourceMultiTenantConnectionProviderImpl ,
    CurrentTenantIdentifierResolver currentTenantIdentifierResolver) {

    Map<String, Object> hibernateProps = new LinkedHashMap<>();
    hibernateProps.putAll(this.jpaProperties.getProperties());
    hibernateProps.put(Environment.MULTI_TENANT, MultiTenancyStrategy.DATABASE);
    hibernateProps.put(Environment.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProvider);
    hibernateProps.put(Environment.MULTI_TENANT_IDENTIFIER_RESOLVER, TenantIdentifierResolverImpl );


    // No dataSource is set to resulting entityManagerFactoryBean
    LocalContainerEntityManagerFactoryBean result = new LocalContainerEntityManagerFactoryBean();
    result.setPackagesToScan(new String[] { Test.class.getPackage().getName() });
    result.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
    result.setJpaPropertyMap(hibernateProps);

    return result;
}

这是在休眠中配置的连接提供者

public class DataSourceMultiTenantConnectionProviderImpl extends 
AbstractDataSourceBasedMultiTenantConnectionProviderImpl {

private static final long serialVersionUID = 1L;

@Autowired
private Map<String, DataSource> dataSources;

@Override
protected DataSource selectAnyDataSource() {
    return this.dataSources.values().iterator().next();
}

@Override
protected DataSource selectDataSource(String tenantIdentifier) {
    return this.dataSources.get(tenantIdentifier);
}
}

这是提供给休眠的租户解析器

public class TenantIdentifierResolverImpl implements 
CurrentTenantIdentifierResolver {

private static String DEFAULT_TENANT_ID = "tenant_1";

@Override
public String resolveCurrentTenantIdentifier() {
    String currentTenantId = TenantContext.getTenantId();
    return (currentTenantId != null) ? currentTenantId : DEFAULT_TENANT_ID;
}

@Override
public boolean validateExistingCurrentSessions() {
    return true;
}
}

这里如何处理连接池?

【问题讨论】:

    标签: java hibernate spring-boot multi-tenant c3p0


    【解决方案1】:

    您可能需要将数据源 bean 更改为:

        @Bean(name = "dataSources" )
    public Map<String, ComboPooledDataSource> dataSources() throws PropertyVetoException {
        Map<String, ComboPooledDataSource> result = new HashMap<>();
        for (DataSourceProperties dsProperties : this.multiTenantProperties.getDataSources()) {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            ds.setDriverClass(dsProperties.getDriverClassName());
            ds.setJdbcUrl(dsProperties.getUrl());
            ds.setUser(dsProperties.getUsername());
            ds.setPassword(dsProperties.getPassword());
            ds.setInitialPoolSize(5);
            ds.setMinPoolSize(1);
            ds.setAcquireIncrement(1);
            ds.setMaxPoolSize(5);
            result.put(dsProperties.getTenantId(), ds);
        }   
    
        return result;
    }
    

    并将此方法添加到您的 DataSourceMultiTenantConnectionProviderImpl

    @Override
    public Connection getConnection(String tenantIdentifier) throws SQLException {
        return this.dataSources.get(tenantIdentifier).getConnection();
    }
    

    这应该足以使用 C3P0 启动连接池。

    【讨论】:

    • 这是有道理的,因为我没有使用 C3P0 的数据源,我无法添加池选项。
    猜你喜欢
    • 2014-02-09
    • 2018-04-16
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2021-11-07
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多