Grails 2 服务中的多个动态数据源 [英] Grails 2 multiple dynamic datasources in services

查看:27
本文介绍了Grails 2 服务中的多个动态数据源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 Grails 应用程序,我必须访问多个数据源.数据源在默认数据库中定义(即,它们存储在那里,我必须调用默认数据库来检索我必须准备连接的数据源名称列表).当服务器启动时,我检索数据库列表,创建数据源 bean 并注入它们.所有动态添加的数据库在结构上都是相同的(即具有相同的表和域对象结构).

I am working on a Grails application where I must access several datasources. The datasources are defined in the default database (ie. they are stored there and I must make a call to the default database to retrieve a list of the datasource names I must prepare to connect to). When the server boots up I retrieve the list of databases, create the datasource beans and inject them. All dynamically added databases are structurally identical (ie. have the same table and domain object structure).

这个问题是我最接近的一段有用的代码,但不是我需要的.

This question is the closest I got to a useful piece of code, but it's not quite what I need.

  • 当我注册数据源 bean 时,它们出现在我期望的位置,但 Grails 没有选择它们.

这是我添加它们的方式:

This is how I add them:

// 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]

当我这样做时,我可以对默认数据源执行操作,仅此而已.

When I do this, I can execute operations on the default datasource, and that's it.

  • 如果我将所有数据源声明为 Datasource.groovy 文件的一部分,那么我可以对所有数据库执行操作,但不能对 如文档所宣传
  • 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

如果我对域对象进行静态映射,它会起作用:

It works if I do the static mapping on my domain objects:

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

但我想要的是将所有这些作为服务的一部分来执行,并声明我的域对象使用所有数据源.

but what I want is to perform all this as part of a service, and declaring my domain objects to use ALL datasources.

在服务中声明数据源不起作用:

Declaring the datasource in the service is not working:

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
  }
}

无论如何,这将始终使用默认数据源.它使用正确数据源的唯一时间是在域对象上我列出了有问题的数据源.

This will always use the default datasource no matter what. The only time when it uses the correct datasource is if on the domain object I list the datasource in question.

所以,有没有人:

  1. 尝试添加动态数据源并成功?

  1. tried adding dynamic datasources and succeeded?

使用 grails 服务在数据源之间切换?

switched between datasources using grails services?

(这将是一个很棒的额外功能,作为顶部的樱桃")使用具有 Spring 安全核心的多个数据源取得成功?安全插件的数据源怎么切换?

(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?

谢谢

--

推荐答案

我有两个不同的数据源使用 Grails 2.3.11.我的 H2 数据库使用 1 个数据源,Oracle db 使用另一个数据源.我不得不在 Grails 2.3 中使用 Hibernate 4.在我的 BuildConfig.groovy 中,我指定了对 hibernate 4 的依赖:

I've got two different datasources working with Grails 2.3.11. I'm using 1 datasource for my H2 database and another for an Oracle db. I had to use Hibernate 4 with Grails 2.3. In my BuildConfig.groovy I specified the dependency on hibernate 4:

runtime ":hibernate4:4.3.5.4"

在我的 DataSource.groovy 文件中,我使用了以下 Hibernate 缓存设置:

In my DataSource.groovy file I used the following Hibernate caching settings:

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 错误,同一个 VM 中已经存在另一个未命名的 CacheManager".在 https://jira.grails.org/browse/GPCACHEEHCACHE-13,但是一旦我将设置放到位,错误就消失了.)

(SIDE NOTE: without the cache settings, I was getting following CacheManager error, "Another unnamed CacheManager already exists in the same VM". There's an open bug report on this at https://jira.grails.org/browse/GPCACHEEHCACHE-13, but once I put the settings in place the error was gone.)

然后我定义了我的数据源:

then I defined my datasources:

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 db,我将 Oracle 数据源指定为:

By default, my Domain classes use the H2 db and I specify my Oracle datasource as:

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 注入我的其他数据源.

Above, I allow the dependency injection to provide the service with the oracle datasource, def dataSource_oracle. If I want to use the H2 datasource, I declare the datasource as def dataSource and allow the DI to inject my other datasource.

我无法让这两个数据源按照 http://grails.github.io/grails-doc/2.3.11/guide/conf.html#multipleDatasources.通过将数据源声明为 dataSource 和 dataSource_lookup 然后将其用作:

I could not get the two datasources to work as specified in the documentation at http://grails.github.io/grails-doc/2.3.11/guide/conf.html#multipleDatasources. By declaring the datasources as dataSource and dataSource_lookup then using it as:

class DataService {
   static datasource = 'lookup'

   void someMethod(...) {
      …
   }
} 

但是我能够使用上述解决方案使其工作.

这篇关于Grails 2 服务中的多个动态数据源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆