Grails2服务中的多个动态数据源

Grails2服务中的多个动态数据源,grails,datasource,Grails,Datasource,我正在开发一个Grails应用程序,在这个应用程序中,我必须访问多个数据源。数据源在默认数据库中定义(即,它们存储在那里,我必须调用默认数据库来检索我必须准备连接的数据源名称列表)。当服务器启动时,我检索数据库列表,创建数据源bean并注入它们。所有动态添加的数据库在结构上都是相同的(即具有相同的表和域对象结构) 是最接近一段有用的代码,但它不是我所需要的 问题1 当我注册数据源bean时,它们会显示在我期望的位置,但Grails不会选择它们 我是这样添加它们的: // Register d

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

是最接近一段有用的代码,但它不是我所需要的

问题1
  • 当我注册数据源bean时,它们会显示在我期望的位置,但Grails不会选择它们
我是这样添加它们的:

// 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]
当我这样做时,我可以在默认数据源上执行操作,就是这样

问题2
  • 如果我将所有数据源声明为
    Datasource.groovy
    文件的一部分,那么我可以在所有数据库上执行操作,但不能
如果我在域对象上执行静态映射,它就会起作用:

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
  }
}
无论发生什么情况,都将始终使用默认数据源。它使用正确数据源的唯一时间是在域对象上列出有问题的数据源


那么,有没有人:

  • 尝试添加动态数据源并成功

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

  • (这将是一个奇妙的额外功能,因为上面有一个“樱桃”)成功地使用了多个数据源和SpringSecurityCore?如何切换安全插件的数据源

  • 谢谢


    --

    您可以在单个应用程序中添加多个数据源,并在服务中访问它们

    首先,您需要在resources.groovy中添加基本数据源

    第一个导入源

    import org.apache.commons.dbcp.BasicDataSource;
    
    然后

    然后可以使用连接对象


    我认为它应该有助于

    使用grails的sharding插件来解决您的问题

    我曾参与过类似的项目,其中应用程序必须从默认数据库检索数据源列表(连接字符串),并连接到每个数据源,并使用quartz作业执行操作

    我像这样实现了它,连接到应用程序中的每个数据源(不是从DataSorce.groovy),并编写SQL而不是tahn 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查询。执行“sql语句”
    并关闭
    sql
    连接。是
    Sql
    类文档。

    我有两个不同的数据源使用Grails2.3.11。我使用1个数据源作为我的H2数据库,另一个用于Oracle数据库。我必须在Grails2.3中使用Hibernate4。在我的
    BuildConfig.groovy
    中,我指定了对hibernate 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错误,“同一个VM中已经存在另一个未命名的CacheManager”。在上有一个打开的错误报告,但一旦我将设置放置到位,错误就消失了。)

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

    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数据源指定为:

    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\u oracle
    。如果我想使用H2数据源,我将该数据源声明为
    def datasource
    ,并允许DI注入我的其他数据源


    我无法使这两个数据源按照文档中的指定工作。通过将数据源声明为dataSource和dataSource_lookup,然后将其用作:

    class DataService {
       static datasource = 'lookup'
    
       void someMethod(...) {
          …
       }
    } 
    
    但是我能够用上面描述的解决方案使它工作



    在这一点上,我几乎可以接受任何人告诉我他们已经成功地在多租户(多数据源)模式下运行了Grails,使用Grails服务来决定DB。任何人如果是,如何解决?我还需要一个与此非常类似的场景的帮助。@Kyle您是否能够解决在grails服务中切换数据源的问题?您好,正在尝试清理未回答的问题。你解决了这个问题吗?也许你可以回答你自己的问题。这无助于回答原来的问题。他需要从另一个数据库连接(而不是平面文件)动态创建数据源bean。我也有同样的问题。Grails似乎没有一种很好的“友好”方式,可以用主上下文数据源bean重新映射域类。我希望有人能回答我们的问题。。因为在评论中发布这些内容是不合适的。。
    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)
            ...
        }
    }
    
    class DataService {
       static datasource = 'lookup'
    
       void someMethod(...) {
          …
       }
    }