Как лучше всего управлять несколькими динамически создаваемыми базами данных с помощью Spring и Hibernate? - PullRequest
2 голосов
/ 08 февраля 2011

Допустим, для каждого клиента необходимо динамически создать базу данных, когда клиент подписывается на услуги, все базы данных основаны на одной схеме.

Поскольку клиенты проходят проверку подлинности (одна основная база данных, управляющая всеми данными клиента), их уникальное имя пользователя используется для доступа к соответствующей базе данных и получения необходимой информации.

Вопрос 1 : Можно ли считать вышесказанное хорошим подходом к такого рода проблеме или есть лучшее решение?

Вопрос 2 : Если нет лучшего решения, как это можно реализовать с помощью Spring & Hibernate?

Редактировать: мне нужно знать, как реализовать создание источника данных по подписке клиента без редактирования файла конфигурации Spring. Это должно быть автоматизировано.

Ответы [ 2 ]

6 голосов
/ 08 февраля 2011

Вопрос 1: Существуют различные варианты. Эта статья рассказывает об этих опциях с плюсами и минусами каждого варианта.

Вопрос 2:

  1. Spring поддерживает маршрутизацию динамических источников данных . Может быть, вы должны начать оттуда.
  2. Вы также можете создавать источники данных динамически при условии, что вы разрешите Spring управлять источниками данных за вас . Все, что вам нужно сделать, это зарегистрировать компонент типа com.mchange.v2.c3p0.ComboPooledDataSource или org.apache.commons.dbcp.BasicDataSource в запущенном приложении Spring ctx. Прочтите статью Как изменить свой applicationContext во время выполнения , как это сделать.

Относящиеся

  1. Настройка источника данных Spring для режима гибернации и @ Transactional
  2. ДБХП
  3. c3p0
3 голосов
/ 11 февраля 2015

Я довольно долго боролся с этой проблемой, и мне удалось ее взломать! Таким образом, при добавлении новой БД для клиента база данных мгновенно становится доступной через программное обеспечение, поскольку у каждого клиента есть выделенная БД, и схема проекта одинакова.

Источник данных изменяется во время выполнения для подключения к нужной вам БД. Как правило, нашим соглашением является то, что имя учетной записи пользователя является именем Db, например. https://serverurl/accountname

Вот разбивка:

applicationContext.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-адресе клиента.

Надеюсь, это поможет кому-то, кто подвергается такой головной боли.

Ура!

...