对于我的应用程序,我需要在运行时动态数据库连接。 我知道,有很多方法可以创建多个数据源,但我认为它们不是动态的。 情形:
用户可以输入数据库凭据并连接到远程数据库,以将单个行和表导入到其他数据库。为此,我需要动态连接到远程数据库。
我试图在他们在If I use groovy sql class in grails, does it use the grails connection pooling?
中所说的服务中做到这一点注意:在这种情况下GORM是可有可无的,我可以使用普通的SQL。
有什么想法吗?谢谢..
编辑:Grails 2.3.4
答案 0 :(得分:8)
您可以在运行时注册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插件,该插件使用本文中概述的方法允许在运行时添加/删除数据源。
答案 1 :(得分: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....