【问题标题】:Grails: Create dynamic SQL-ConnectionGrails:创建动态 SQL 连接
【发布时间】:2023-03-14 18:45:01
【问题描述】:

对于我的应用程序,我需要在运行时进行动态数据库连接。 我知道,有很多方法可以创建多个数据源,但我认为它们并不是动态的。 场景:

用户可以输入数据库凭据并连接到远程数据库以将单个行和表导入其他数据库。为此,我需要动态连接到远程数据库。

我已经尝试在他们在If I use groovy sql class in grails, does it use the grails connection pooling? 中所说的服务中做到这一点

注意:在这种情况下 GORM 是可有可无的,我可以使用纯 SQL 代替。

有什么想法吗?谢谢。。

编辑:Grails 2.3.4

【问题讨论】:

  • 什么版本的 Grails?这些数据源是否需要在多次调用中持续存在,还是您只需要连接、获取一些数据并断开连接?
  • @tim_yates 这是 Grails 2.3.4。理想的解决方案是我可以打多个电话。如果不可能,那么更简单的解决方案就足够了。

标签: sql grails groovy grails-orm


【解决方案1】:

您可以通过这种方式在运行时注册 DataSource bean:

给定一个 Grails 服务:

package whatever

import groovy.sql.Sql
import org.springframework.context.*
import org.apache.tomcat.jdbc.pool.DataSource
import org.springframework.context.support.GenericApplicationContext

class DataSourceService implements ApplicationContextAware {

    ApplicationContext  applicationContext

    def registerBean( String beanName, String dsurl, String uid, String pwd ) {
        if( !applicationContext.containsBean( beanName ) ) {
            def bb = new grails.spring.BeanBuilder()
            bb.beans {
                "$beanName"( DataSource ) {
                    driverClassName = "com.mysql.jdbc.Driver"
                    url             = dsurl
                    username        = uid
                    password        = pwd
                    validationQuery = "SELECT 1"
                    testOnBorrow    = true
                    maxActive       = 1
                    maxIdle         = 1
                    minIdle         = 1
                    initialSize     = 1
                }
            }
            bb.registerBeans( applicationContext )
            log.info "Added $beanName"
        }
        else {
            log.error "Already got a bean called $beanName"
        }
    }

    def deRegisterBean( String beanName ) {
        if( applicationContext.containsBean( beanName ) ) {
            (applicationContext as GenericApplicationContext).removeBeanDefinition( beanName )
            log.info "Removed $beanName"
        }
        else {
            log.error "Trying to deRegister a bean $beanName that I don't know about"
        }
    }

    def getSql( String beanName ) {
        Sql.newInstance( applicationContext.getBean( beanName ) )
    }
}

然后,您应该可以调用该服务来注册一个新的数据源:

dataSourceService.registerBean( 'myDS', 'jdbc:mysql://localhost:3306/mysql', 'test', 'test' )

为它获取一个 Groovy Sql 对象:

dataSourceService.getSql( 'myDS' ).rows( 'SELECT * FROM whatever' )

完成后移除 bean

dataSourceService.deRegisterBean( 'myDS' )

手指交叉...我从我的一个项目中提取了该代码并对其进行了更改/未测试;-)

更新

runtime-datasources 插件已创建,它使用本文中概述的方法允许在运行时添加/删除数据源。

【讨论】:

  • 看起来很棒!当我调用 select 时,我只收到问题“驱动程序:com.mysql.jdbc.Driver@75c65470 为 URL:null 返回 null”。谢谢。
  • @n33dle 试试看,我把registerBean方法中的url参数改成了dsurl
  • @n33dle 很高兴为您提供帮助 :-) 玩得开心!
  • 您好,有什么方法可以将新创建​​的数据源用作 GORM 数据源,以便运行 Domain.myDS.list() ?谢谢
  • 我正在努力实现这一目标...stackoverflow.com/questions/22321878/…
【解决方案2】:

只要您的类路径上的所有数据源都有 JDBC 驱动程序,您就可以创建一个 groovy.sql.Sql 实例,该实例将连接到您喜欢的任何数据库,例如

Sql sql = Sql.newInstance('jdbc:hsqldb:mem:testDB', 'sa', 'myPassword', 
    'org.hsqldb.jdbc.JDBCDriver')

// now use the Sql instance to execute a query, or whatever....

【讨论】:

  • 我已经用 def conn = Sql.newInstance("jdbc:mysql://localhost:3306/mysql", "test", "test", "com.mysql.jdbc.驱动程序”),但我总是得到“找不到适合 jdbc:mysql://localhost:3306/mysql 的驱动程序”。依赖加载在 BuildConfig.groovy
  • 你的classpath里好像没有MySQL JDBC驱动,能不能把BuildConfig.groovy的相关部分显示一下?
  • 依赖{运行时'mysql:mysql-connector-java:5.1.24'}
猜你喜欢
  • 2010-12-25
  • 1970-01-01
  • 1970-01-01
  • 2021-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多