我正在开发一个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服务在数据源之间切换?
(这将是一个很棒的额外内容,因为"顶部的樱桃")成功地使用带有 Spring 安全核心的多个数据源?如何切换安全插件的数据源?
谢谢
--
我有两个不同的数据源使用Grails 2.3.11。我正在为我的 H2 数据库使用 1 个数据源,将另一个数据源用于 Oracle 数据库。我不得不将Hibernate 4与Grails 2.3一起使用。在我的BuildConfig.groovy
中,我指定了对休眠 4 的依赖关系:
runtime ":hibernate4:4.3.5.4"
在我的DataSource.groovy
文件中,我使用了以下休眠缓存设置:
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
}
(旁注:如果没有缓存设置,我会收到以下缓存管理器错误,"同一虚拟机中已存在另一个未命名的缓存管理器"。https://jira.grails.org/browse/GPCACHEEHCACHE-13 有一个关于此的开放错误报告,但是一旦我设置到位,错误就消失了。
然后我定义了我的数据源:
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)
...
}
}
上面,我允许依赖注入为服务提供预言机数据源,def dataSource_oracle
.如果我想使用 H2 数据源,我将数据源声明为 def dataSource
并允许 DI 注入我的其他数据源。
我无法按照 http://grails.github.io/grails-doc/2.3.11/guide/conf.html#multipleDatasources 文档中的规定让这两个数据源工作。通过将数据源声明为数据源,dataSource_lookup然后将其用作:
class DataService {
static datasource = 'lookup'
void someMethod(...) {
…
}
}
但我能够让它与上述解决方案一起工作。
我从事过类似的项目,其中应用程序必须从默认数据库中检索数据源(连接字符串)列表,并连接到每个数据源并使用石英作业执行操作。
我实现了它,连接到应用程序中的每个数据源(不是来自DataSorce.groovy)并编写SQL而不是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.execute "SQL STATEMENT"
执行 SQL 查询并关闭sql
连接。这是Sql
类文档。
您可以在单个应用程序中添加多个数据源,并在服务中访问它们。
首先,您需要在 resources.groovy 中添加基本数据源。
首次导入基本数据源
import org.apache.commons.dbcp.BasicDataSource;
然后
switch (grails.util.GrailsUtil.environment) {
case "development":
firstDataSource( BasicDataSource ) {
driverClassName = "net.sourceforge.jtds.jdbc.Driver"
url = "jdbc:jtds:sqlserver://localhost:1433;DatabaseName=<Db_name>"
username = "sa"
password = "root"
String SqlServerInstance = "SQLEXPRESS";
url = url + ";" + SqlServerInstance;
}
break
case "test":
firstDataSource( BasicDataSource ) {
driverClassName = "net.sourceforge.jtds.jdbc.Driver"
url = "jdbc:jtds:sqlserver://localhost:1433;DatabaseName=<Db_name>"
username = "sa"
password = "root"
String SqlServerInstance = "SQLEXPRESS";
url = url + ";" + SqlServerInstance; }
break;
}
以同样的方式,您可以添加更多数据源,上面的代码将为您提供一个默认数据源以外的多个数据源。我使用 switch 为不同的环境配置相同的数据源,以同样的方式可以添加更多数据源。
在服务中,可以在服务中按以下方式访问它:
BasicDataSource firstDataSource;
Connection con = firstDataSource.getConnection();
然后可以使用连接对象。
我认为它应该有所帮助
片插件来解决您的问题