首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >spring中的多租户应用程序-连接到数据库

spring中的多租户应用程序-连接到数据库
EN

Stack Overflow用户
提问于 2017-12-05 18:14:40
回答 1查看 182关注 0票数 1

各位专家,

我正在做一个多租户项目。它是每个租户架构的一个表。

为此,我们使用了spring和JPA (eclipse-link)。在这里,我们的用例是当新客户订阅我们的应用程序时,将为该客户创建一个新的数据库。

由于弹簧配置只会在启动时加载,如何在运行时加载这个新的数据库配置?

有人能给点建议吗?提前谢谢。

BR,凯蒂

EN

回答 1

Stack Overflow用户

发布于 2017-12-05 20:48:06

对于multitenan,首先你需要创建如下文件所示的MultitenantConfig.java。其中,tenants.get("Musa")是我的租户名称,来自application.properties文件

代码语言:javascript
运行
复制
 @Configuration
    @EnableConfigurationProperties(MultitenantProperties.class)
    public class MultiTenantConfig extends WebMvcConfigurerAdapter {

        /** The Constant log. */
        private static final Logger log = LoggerFactory.getLogger(MultiTenantConfig.class);

        /** The multitenant config. */
        @Autowired
        private MultitenantProperties multitenantConfig;

        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new MultiTenancyInterceptor());
        }

        /**
         * Data source.
         *
         * @return the data source
         */
        @Bean
        public DataSource dataSource() {

            Map<Object, Object> tenants = getTenants();

            MultitenantDataSource multitenantDataSource = new MultitenantDataSource();
            multitenantDataSource.setDefaultTargetDataSource(tenants.get("Musa"));
            multitenantDataSource.setTargetDataSources(tenants);

            // Call this to finalize the initialization of the data source.
            multitenantDataSource.afterPropertiesSet();

            return multitenantDataSource;
        }

        /**
         * Gets the tenants.
         *
         * @return the tenants
         */
        private Map<Object, Object> getTenants() {
            Map<Object, Object> resolvedDataSources = new HashMap<>();

            for (Tenant tenant : multitenantConfig.getTenants()) {
                DataSourceBuilder dataSourceBuilder = new DataSourceBuilder(this.getClass().getClassLoader());
                dataSourceBuilder.driverClassName(tenant.getDriverClassName()).url(tenant.getUrl())
                        .username(tenant.getUsername()).password(tenant.getPassword());
                DataSource datasource = dataSourceBuilder.build();

                for (String prop : tenant.getTomcat().keySet()) {
                    try {
                        BeanUtils.setProperty(datasource, prop, tenant.getTomcat().get(prop));
                    } catch (IllegalAccessException | InvocationTargetException e) {
                        log.error("Could not set property " + prop + " on datasource " + datasource);
                    }
                }

                log.info(datasource.toString());
                resolvedDataSources.put(tenant.getName(), datasource);
            }

            return resolvedDataSources;
        }

    }


public class MultitenantDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return TenantContext.getCurrentTenant();
    }
}



public class MultiTenancyInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) {
        TenantContext.setCurrentTenant("Musa");
        return true;
    }
}



 @ConfigurationProperties(prefix = "multitenancy")
public class MultitenantProperties {

    public static final String CURRENT_TENANT_IDENTIFIER = "tenantId";
    public static final int CURRENT_TENANT_SCOPE = 0;

    private List<Tenant> tenants;

    public List<Tenant> getTenants() {
        return tenants;
    }

    public void setTenants(List<Tenant> tenants) {
        this.tenants = tenants;
    }    
}



  public class Tenant {

    private String name;
    private String url;
    private String driverClassName;
    private String username;
    private String password;
    private Map<String,String> tomcat;

//setter gettter

代码语言:javascript
运行
复制
public class TenantContext {
    private static ThreadLocal<Object> currentTenant = new ThreadLocal<>();
    public static void setCurrentTenant(Object tenant) {
        currentTenant.set(tenant);
    }
    public static Object getCurrentTenant() {
        return currentTenant.get();
    }
}

在application.properties中添加以下属性

代码语言:javascript
运行
复制
multitenancy.tenants[0].name=Musa
multitenancy.tenants[0].url<url>
multitenancy.tenants[0].username=<username>
multitenancy.tenants[0].password=<password>
multitenancy.tenants[0].driver-class-name=<driverclass>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47651061

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档