Вопрос по – Grails 2 множественных динамических источника данных в сервисах

12

Я работаю над приложением Grails, где мне нужно получить доступ к нескольким источникам данных. Источники данных определены в базе данных по умолчанию (т.е. они хранятся там, и я должен позвонить в базу данных по умолчанию, чтобы получить список имен источников данных, к которым я должен подготовиться для подключения). Когда сервер загружается, я извлекаю список баз данных, создаю компоненты источника данных и внедряю их. Все динамически добавленные базы данных структурно идентичны (т. Е. Имеют одинаковую структуру таблицы и объекта домена).

Этот вопрос ближе всего к полезному коду, но это не совсем то, что мне нужно.

Issue #1 When I register the datasource beans, they show up where I expect, but Grails does not pick them up.

Вот как я их добавляю:

// Register datasource bean
def beanName = 'dataSource_devDB1'

BeanBuilder bb = new BeanBuilder()
bb.beans {
    "${beanName}"(BasicDataSource) { 
        url = "jdbc:h2:devDB1Db;MVCC=TRUE"
        pooled = true
        driverClassName = "org.h2.Driver"
        username = "sa"
        password = ""            
    }
}

bb.registerBeans(grailsApplication.mainContext)

// check that it registered
def ctx = grailsApplication.mainContext
def ctxlist = ctx2.beanDefinitionNames.findAll{it.contains( 'dataSource' )}

log.info "ctxlist = " + ctxlist

Это печатает:

[dataSource, dataSourceUnproxied, dataSource_devDB1]

Когда я делаю это, я могу выполнять операции с источником данных по умолчанию, и это все.

Issue #2 If I declare all my datasources as part of the Datasource.groovy file, then I can execute operations on all my databases, but not as advertised by the documentation

Это работает, если я делаю статическое отображение на моих объектах домена:

static mapping = {datasources(['devDB1', 'devDB2', 'DEFAULT')] or datasource = 'ALL'

но я хочу выполнить все это как часть службы и объявить объекты моего домена для использования ВСЕХ источников данных.

Объявление источника данных в службе не работает:

class secureDBService{

  static datasource = "devDB1"

  def readWriteMethod(){
   .....
  // this always uses the default datasource ignoring the static property above.
  // the only time it uses devDB1 is if I declare it as part of the domain datasource
  // mapping
  }
}

Это всегда будет использовать источник данных по умолчанию, несмотря ни на что. Единственный раз, когда он использует правильный источник данных, это если в доменном объекте я перечисляю соответствующий источник данных.

Итак, есть кто-нибудь:

tried adding dynamic datasources and succeeded?

switched between datasources using grails services?

(and this would be a fantastic extra , as a "cherry on top") had success using multiple datasource with spring security core? How do you switch the datasource for the security plugin?

Спасибо

--

@ Kyle Удалось ли решить проблему переключения источников данных в сервисах Grails? Lalit Agarwal
Ты это решил? Sérgio Michels
На данный момент я почти согласен на то, что кто-то скажет мне, что они успешно запустили Grails в мультитенантном режиме (с несколькими источниками данных), используя службы Grails для определения БД. Кто угодно? Если да, то как? Kyle
Мне также нужна помощь по очень похожему сценарию. Thomas Farvour

Ваш Ответ

3   ответа
1

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

Я реализовал это, как, подключиться к каждому источнику данных в приложении (не из DataSorce.groovy) и писать SQL, а не HQL.

,
import groovy.sql.Sql

class SqlService{
    Sql getDbConnection(String connectionString, String dbUser, String dbPassword){
        def sql = Sql.newInstance(connectionString, dbUser, dbPassword, "driver_class")
        return sql
    }
}

Получитьsql соединение из приведенного выше кода и выполнение SQL-запросов с помощьюsql.execute "SQL STATEMENT" и закройsql соединение.Во этоSql учебная документация.

1

работающих с Grails 2.3.11. Я использую один источник данных для моей базы данных H2 и другой для базы данных Oracle. Мне пришлось использовать Hibernate 4 с Grails 2.3. В моемBuildConfig.groovy Я указал зависимость от спящего режима 4:

runtime ":hibernate4:4.3.5.4"

В моемDataSource.groovy файл Я использовал следующие настройки кэширования Hibernate:

hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = false
    cache.region.factory_class = 'org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory'
    singleSession = true // configure OSIV singleSession mode
}

(Боковое примечание: без настроек кэша я получаю следующую ошибку CacheManager: «В той же виртуальной машине уже существует другой безымянный CacheManager». Наhttps: //jira.grails.org/browse/GPCACHEEHCACHE-1, но как только я установил настройки на место, ошибка исчезла.)

затем я определил свои источники данных:

environments {
    development {
        dataSource_oracle {
            pooled = true
            dialect = org.hibernate.dialect.Oracle10gDialect
            driverClassName = 'oracle.jdbc.OracleDriver'
            username = 'user'
            password = 'pass'
            url = 'jdbc:oracle:thin:@(serverName):(port):(SID)'
            dbCreate = 'validate'
        }
        dataSource {
            dbCreate = "update"
            url = "jdbc:h2:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
            properties {
               jmxEnabled = true
               initialSize = 5
               maxActive = 50
               minIdle = 5
               maxIdle = 25
               maxWait = 10000
               maxAge = 10 * 60000
               timeBetweenEvictionRunsMillis = 5000
               minEvictableIdleTimeMillis = 60000
               validationQuery = "SELECT 1"
               validationQueryTimeout = 3
               validationInterval = 15000
               testOnBorrow = true
               testWhileIdle = true
               testOnReturn = false
               jdbcInterceptors = "ConnectionState"
               defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED
            }
        }
    }
}

По умолчанию, мои классы Домена используют базу данных H2, и я указываю свой источник данных Oracle как:

class MyService {

    def dataSource_oracle
    static transactional = true

    def getMethod() {
        assert dataSource_oracle != null, "dataSource is null! Please check your configuration!"
        def sql = Sql.newInstance(dataSource_oracle)
        ...
    }
}

Выше я разрешаю внедрение зависимостей для предоставления сервиса с источником данных oracle,def dataSource_oracle. Если я хочу использовать источник данных H2, я объявляю источник данных какdef dataSource и разрешить DI ввести другой источник данных.

Я не смог заставить работать два источника данных, как указано в документации вhttp: //grails.github.io/grails-doc/2.3.11/guide/conf.html#multipleDatasource. Объявляя источники данных как dataSource и dataSource_lookup, затем используя их как:

class DataService {
   static datasource = 'lookup'

   void someMethod(...) {
      …
   }
} 

но Я смог заставить его работать с решением, описанным выше.

0

лучать к ним доступ в службах.

Сначала вам нужно добавить основные источники данных в resources.groovy.

first import BasicDataSource

import org.apache.commons.dbcp.BasicDataSource;

Зате

    switch (grails.util.GrailsUtil.environment) {
    case "development":
        firstDataSource( BasicDataSource ) {
            driverClassName = "net.sourceforge.jtds.jdbc.Driver"
            url = "jdbc:jtds:sqlserver://localhost:1433;DatabaseName=<Db_name>"
            username = "sa"
            password = "root"
            String SqlServerInstance = "SQLEXPRESS";
            url = url + ";" + SqlServerInstance;
        }
        break

    case "test":
        firstDataSource( BasicDataSource ) {

            driverClassName = "net.sourceforge.jtds.jdbc.Driver"
            url = "jdbc:jtds:sqlserver://localhost:1433;DatabaseName=<Db_name>"
            username = "sa"
            password = "root"
            String SqlServerInstance = "SQLEXPRESS";
            url = url + ";" + SqlServerInstance;            }
        break;

}

Так же, как вы можете добавить больше источников данных, приведенный выше код предоставит вам еще один источник данных для доступа, отличный от источника по умолчанию. Я использовал switch для настройки одного и того же источника данных для разных сред, таким же образом можно добавить больше.

и в сервисе он может быть доступен в сервисах как:

BasicDataSource firstDataSource;
Connection con = firstDataSource.getConnection();

и тогда можно использовать объект подключения.

Думаю, это должно помочь

Это не поможет ответить на исходный вопрос. Ему нужно динамически создавать бины источника данных из другого соединения с базой данных, а не из простого файла. У меня та же проблема. Не похоже, что у Grails есть хороший «дружественный» способ перезагрузки доменных классов с bean-компонентами dataSource основного контекста. Надеюсь, кто-нибудь ответит на наши вопросы. Thomas Farvour
хммм может быть .. я думал, что это может помочь .. потому что публиковать все это в комментариях было бы неуместно .. Saurabh Dixit

Похожие вопросы