2

假设对于每个客户,您必须在客户订阅服务时动态创建一个数据库,所有数据库都基于相同的模式。

当客户通过身份验证(一个管理所有客户详细信息的主数据库)时,他们的唯一用户名用于访问相应的数据库并检索所需的信息。

问题1:以上可以被认为是解决这类问题的好方法还是有更好的解决方案?

问题 2:如果没有更好的解决方案,如何使用 Spring & Hibernate 来实现?

编辑:我需要知道的是如何在不编辑 Spring 配置文件的情况下在客户订阅时实现数据源创建。它需要自动化。

4

2 回答 2

6

问题1:有多种选择。本文讨论了这些选项以及每个选项的优缺点。

问题2:

  1. Spring 支持动态数据源路由。也许你应该从那里开始。
  2. 您还可以动态创建数据源,前提是让 Spring 为您管理数据源。您所要做的就是在正在运行的 Spring 应用程序 ctx 中注册一个com.mchange.v2.c3p0.ComboPooledDataSourceorg.apache.commons.dbcp.BasicDataSource类型的 bean。阅读文章在运行时更改您的 applicationContext 以了解如何执行此操作。

有关的

  1. 为hibernate和@Transactional配置spring数据源
  2. DBCP
  3. c3p0
于 2011-02-08T04:04:51.557 回答
3

我在这个问题上挣扎了很长一段时间,我设法破解了它!这样,如果为客户端添加了新的数据库,则可以通过软件立即访问该数据库,因为每个客户端都有一个专用的数据库并且架构设计是相同的。

数据源在运行时被修改以连接到您想要的数据库。通常,我们的约定是用户的帐户名是 Db 名称,例如https://serverurl/accountname

这是细分:

应用程序上下文.xml

<bean id="dataSource" class="com.package.util.TenantRouter">
    <property name="targetDataSources">
        <map>
            <entry key="db" value-ref="db"/>
        </map>
    </property>
    <property name="defaultTargetDataSource" ref="parentDataSource"/>
</bean>

<bean id="parentDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.postgresql.Driver"/>
    <property name="url" value="jdbc:postgresql://localhost:6432/db?autoReconnect=true"/>
    <property name="username" value="DBUSER"/>
    <property name="password" value="DBPASS"/>
</bean>

<bean id="db" parent="parentDataSource">
    <property name="url" value="jdbc:postgresql://localhost:5432/db?autoReconnect=true"/>
    <property name="username" value="DBUSER"/>
    <property name="password" value="DBPASS"/>
</bean>

在 TenantRouter 类中,这两个方法是命令式的:

@Override
protected Object determineCurrentLookupKey() {
    String tenant="defaultdb";
    if (UserContextUtil.getUserContext()!=null){
        tenant = UserContextUtil.getUserContext().getTenant().toString();
    }
    return tenant;
}

@Override
protected DataSource determineTargetDataSource() {
    //current DB
    String db_name = (String) determineCurrentLookupKey();
    //System.out.println("THIS DB:"+db_name);
    DriverManagerDataSource ds = new DriverManagerDataSource();  
    ds.setDriverClassName("org.postgresql.Driver"); 

    String url="jdbc:postgresql://localhost:5432/"+db_name+"?autoReconnect=true";
    //System.out.println("URL:"+url);
    ds.setUrl(url);  
    ds.setUsername(username);  
    ds.setPassword(password);
    return ds;
}

UserContextUtil.getUserContext().getTenant().toString()返回客户端 URL 中提供的要连接的请求 Db 。

我希望这对经历这种头痛的人有所帮助。

干杯!

于 2015-02-11T17:04:18.270 回答