将两个数据库用于grails中的应用程序

时间:2010-11-11 09:15:53

标签: database grails

我在grails中创建一个应该从一个数据库读取并写入另一个数据库的应用程序。我为此要求创建了datasources.groovy并安装了datasources插件。但是,我在执行sql查询时遇到了如何使用这个数据源(select * from ........等等)。

例如。以下是我在操作中运行查询的方法。我使用的是自定义查询而不是gorm。

编辑:

class TuneController {   

    def dataSource_ds2

    def list = {

        String nameSql = "select name from emp where id=3345"
        Sql sql = new Sql(dataSource_ds2)
        String name = sql.rows(nameSql)
        println(name)
    }
}

在上述情况下,不读取数据源并且具有空值。 是否有可用于此要求的示例代码。

我在这里错过了什么吗?

编辑:

我的Datasources.groovy条目如下。

datasources = { 

    datasource(name:'ds2') {
        domainClasses([com.Tune])
        readOnly(true)
        driverClassName('oracle.jdbc.driver.OracleDriver')
        url('jdbc:oracle:thin:@test-ofr.wellmanage.com:1521:OFRS1')         
        username('test')
        password('test')
        environments(['development'])
        dbCreate('do-not-bother')
        logSql(true)
        dialect(org.hibernate.dialect.Oracle10gDialect)
        hibernate {
            cache {
                use_second_level_cache(false)
                use_query_cache(false)
            }
        }
    }
}

6 个答案:

答案 0 :(得分:5)

辅助数据源可以使用依赖注入,但它们的名称基于Datasources.groovy中的名称。例如,如果您已经定义了一个名为'foo'的数据源,那么您可以使用def dataSource_foo注入该数据源:

class MyController {

   def dataSource_foo

   def list = {
      String nameSql = "select name from emp where id=3345"
      Sql sql = new Sql(dataSource_foo)
      def rows = sql.rows(nameSql)
      ...
   }
}

请注意,您必须将def dataSource_foo作为类范围字段而不是您的操作(或方法)。每次依赖注入都是如此 - 如果它在方法或闭包内,它只是一个方法范围变量。

答案 1 :(得分:2)

只是为了更新这个问题的答案(我刚刚得到了一个新项目,需要使用两个不同的mysql数据库)。我不得不升级到grails 2.0(是的,我一直懒得从1.3.7升级)因为它内置了对多个数据源的支持(不需要使用插件)。

Grails 2.0 - multiple datasources

从示例中,您只需要在DataSource.groovy文件中设置数据库

environments {
development {
    dataSource {
        dbCreate = "create-drop"
        url = "jdbc:h2:mem:devDb"
    }
    dataSource_lookup {
        dialect = org.hibernate.dialect.MySQLInnoDBDialect
        driverClassName = 'com.mysql.jdbc.Driver'
        username = 'lookup'
        password = 'secret'
        url = 'jdbc:mysql://localhost/lookup'
        dbCreate = 'update'
    }
}

然后在域类中,指定哪个数据源:

class ZipCode {

    String code

    static mapping = { datasource 'lookup' } 
 }

答案 2 :(得分:0)

我在上一个项目的BootStrap中做到了这一点。请记住,有效的Java代码也是有效的Groovy(大多数情况下),并且您不必执行“Grails Way”的所有操作。只需以您熟悉的方式连接到“from”数据库,并通过Grails域对象操作将内容存储在Grails数据源中。示例代码:

try {
    Connection con = DriverManager.getConnection ("jdbc:xxxx", "username", "password")
    ResultSet resultSet = con.createStatement().executeQuery("SELECT * FROM the_table")
    while(resultSet.next()) {
        DomainObject domainObjectInstance = new DomainObject(attributeA: resultSet.getString('attributeA'), attributeB: resultSet.getString('attributeB'))
        if (!domainObjectInstance.save(flush: true)) {
            println "Unable to save DomainObject: ${domainObjectInstance.errors}"
        }
    }
} catch (SQLException e) {
    e.printStackTrace();
}

答案 3 :(得分:0)

我将我的dataSource更新为以下内容,并且它有效。我不确定它背后的原因是什么。

 datasources = {  

    datasource(name:'ds2') { 
        domainClasses([com.Tune]) 
        readOnly(true) 
        driverClassName('oracle.jdbc.driver.OracleDriver') 
        url('jdbc:oracle:thin:@test-ofr.tnic.com:1521:OFRS1')          
        username('test') 
        password('test') 
        environments(['development']) 
        dbCreate('do-not-bother') 
        logSql(true) 
        dialect(org.hibernate.dialect.Oracle10gDialect) 
        hibernate { 
            cache { 
               provider_class('net.sf.ehcache.hibernate.EhCacheProvider')
               use_second_level_cache(true)
               use_query_cache(true)
            } 
        } 
    } 
} 

答案 4 :(得分:0)

我想知道为什么没有人在这里提到'c3p0:c3p0:0.9.1.2'插件。

这是在grails应用程序中实现多个数据库的最佳实践

Buildconfig.groovy

compile 'c3p0:c3p0:0.9.1.2'

datasource

 dataSource {
            dialect = 'com.example.hibernateutil.MySQL5InnoDBDialectBitFixed'
            dbCreate = "update" // one of 'create', 'create-drop', 'update', 'validate', ''
            driverClassName = "com.mysql.jdbc.Driver"
            url = "jdbc:mysql://127.0.0.1/demo
            username = "root"
            password = ""
        }

        dataSource_Demo {
            dialect = 'com.example.hibernateutil.MySQL5InnoDBDialectBitFixed'
            dbCreate = "update" // one of 'create', 'create-drop', 'update', 'validate', ''
            driverClassName = "com.mysql.jdbc.Driver"
            url = "jdbc:mysql://127.0.0.1/demo2"
            username = "root"
            password = ""
        }

resources.groovy

beans = {


   dataSource_Demo(ComboPooledDataSource) { bean ->
        bean.destroyMethod = 'close'
        //use grails' datasource configuration for connection user, password, driver and JDBC url
        user = grailsApplication.config.dataSource_Demo.username
        password = grailsApplication.config.dataSource_Demo.password
        driverClass = grailsApplication.config.dataSource_Demo.driverClassName
        jdbcUrl = grailsApplication.config.dataSource_Demo.url
        idleConnectionTestPeriod = 2 * 60 * 60 //2 hours
        testConnectionOnCheckin = true
    }

    /**
     * c3P0 pooled data source that allows 'DB keepalive' queries
     * to prevent stale/closed DB connections
     * Still using the JDBC configuration settings from DataSource.groovy
     * to have easy environment specific setup available
     */
    dataSource(ComboPooledDataSource) { bean ->
        bean.destroyMethod = 'close'
        //use grails' datasource configuration for connection user, password, driver and JDBC url
        user = grailsApplication.config.dataSource.username
        password = grailsApplication.config.dataSource.password
        driverClass = grailsApplication.config.dataSource.driverClassName
        jdbcUrl = grailsApplication.config.dataSource.url
        idleConnectionTestPeriod = 2 * 60 * 60 //2 hours
        testConnectionOnCheckin = true
    }
}

答案 5 :(得分:-1)

如何使用SQL在Grails Services中使用多个数据源的示例。

提示:您可以使用func getVisibleVC() -> UIViewController? { if var visibleVC = window?.rootViewController { while let presentedVC = visibleVC.presentedViewController { visibleVC = presentedVC } return visibleVC } return nil } TestServiceWithInjection。两者都很好。

DataSource.groovy

TestService

<强> TestServiceWithInjection.groovy

dataSource {
    pooled = true
    jmxExport = true
    driverClassName = "com.mysql.jdbc.Driver"
    dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
}
hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = false
//    cache.region.factory_class = 'org.hibernate.cache.SingletonEhCacheRegionFactory' // Hibernate 3
    cache.region.factory_class = 'org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory' // Hibernate 4
    singleSession = true // configure OSIV singleSession mode
    flush.mode = 'manual' // OSIV session flush mode outside of transactional context
}

// environment specific settings
environments {
    development {
        dataSource {
            dbCreate = "update" // one of 'create', 'create-drop', 'update', 'validate', ''
            url = "jdbc:mysql://localhost:3306/database1"
            username = "root"
            password = "password"
        }
        dataSource_second {
            driverClassName = "com.mysql.jdbc.Driver"
            dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
            dbCreate = "update" // one of 'create', 'create-drop', 'update', 'validate', ''
            url = "jdbc:mysql://localhost:3306/database2"
            username = "root"
            password = "password"
        }
    }
    test {
        dataSource {
            //Used by local test run (grails test-app)
            dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
            url = "jdbc:mysql://test-server.com:3306/test_ci"
            username = "root"
            password = "password"
        }
    }
}

<强> TestService.groovy

package com.github.biniama

import grails.transaction.Transactional
import groovy.sql.Sql

import javax.annotation.PostConstruct

@Transactional
class TestService {

    def dataSource_second

    Sql sql

    @PostConstruct
    def initSql() {
        sql = new Sql(dataSource_second)
    }

    def getData() {
        def q = "SELECT id FROM job LIMIT 1"
        return sql.rows(q)
    }
}

}

<强> TestController.groovy

package com.github.biniama

import grails.transaction.Transactional
import groovy.sql.Sql

@Transactional
class TestService {

private Sql sql

void setDataSource_second(def dataSource) {
    sql = new Sql(dataSource)
}

Integer getData() {
    def q = "SELECT id FROM job LIMIT 1"
    return sql.rows(q)
}