Grails - 从不同的数据源获取数据并将其保存在我的 Grails 数据库中
Grails - Getting data from a different datasource and saving it in my Grails database
我有一个 Grails 项目需要从另一个项目 运行 的数据库中检索数据。这个另一个项目是 运行 在不同的平台 (Drupal) 上,并且具有不同的域。我只需要读取这个数据库中的一些表,并将其保存在我自己的数据源中。
完成此任务的最佳方法是什么?
最快的方法是使用 GORM 的 support for multiple datasources,它旨在用于在两个或多个数据库之间划分您的域 classes,但您不必分配任何到第二个数据源。一个小的缺点是,这样做会创建一个额外的事务管理器、Hibernate 会话工厂,以及更多的 classes 和 Spring beans,但它们不会在没有任何东西的情况下占用太多内存使用它们。为此,在 DataSource.groovy
中添加第二个 dataSource
块,并带有唯一后缀(它不会影响除 Spring bean 名称以外的任何内容),例如
dataSource_drupal {
pooled = true
driverClassName = '...'
username = '...'
password = '...'
url = '...'
}
由于此数据源不会用于 GORM,因此您无需指定 dialect
、dbCreate
或 jmxExport
,也不需要第二个 hibernate
块,只有创建连接池所需的信息(默认情况下会创建 10 个初始连接)。
如果您担心这种方法的额外内存(您不应该担心,它将是最小的)您可以做更多的工作并在 [=21] 中手动注册一个 Spring bean =].如果您使用的是最新版本的 Grails,数据源实现是 Tomcat JDBC Connection Pool,因此请使用其驱动程序 class 和 setter 属性 名称来指定连接信息。使用任何有效的 Spring bean 名称,但我会遵循多个数据源支持的约定:
import org.apache.tomcat.jdbc.pool.DataSource
beans = {
dataSource_drupal(DataSource) { bean ->
bean.destroyMethod = 'close'
driverClassName = '...'
url = '...'
username = '...'
password = '...'
// optional extra settings, not really needed
// unless you expect a lot of usage
initialSize = 42
testOnBorrow = true
testWhileIdle = false
testOnReturn = false
validationQuery = 'SELECT 1'
}
}
因此,要使用您的第二个数据源,请将其依赖注入到您将用于执行数据迁移工作的服务中:
def dataSource_drupal
并执行 SQL 查询,最好的选择是 groovy.sql.Sql
,因为它很好地隐藏了与 JDBC 代码相关的大部分仪式。添加导入
import groovy.sql.Sql
并创建一个新实例,将 DataSource
bean 传递给它的构造函数,以便它可以使用它来获取连接:
Sql sql = new Sql(dataSource_drupal)
sql.eachRow('select name, bar from foo' ) { row ->
Foo foo = new Foo(name: row.name, bar: row.bar)
if (!foo.save()) {
log.error "Validation error(s) for data $row: $foo.errors"
}
}
我有一个 Grails 项目需要从另一个项目 运行 的数据库中检索数据。这个另一个项目是 运行 在不同的平台 (Drupal) 上,并且具有不同的域。我只需要读取这个数据库中的一些表,并将其保存在我自己的数据源中。
完成此任务的最佳方法是什么?
最快的方法是使用 GORM 的 support for multiple datasources,它旨在用于在两个或多个数据库之间划分您的域 classes,但您不必分配任何到第二个数据源。一个小的缺点是,这样做会创建一个额外的事务管理器、Hibernate 会话工厂,以及更多的 classes 和 Spring beans,但它们不会在没有任何东西的情况下占用太多内存使用它们。为此,在 DataSource.groovy
中添加第二个 dataSource
块,并带有唯一后缀(它不会影响除 Spring bean 名称以外的任何内容),例如
dataSource_drupal {
pooled = true
driverClassName = '...'
username = '...'
password = '...'
url = '...'
}
由于此数据源不会用于 GORM,因此您无需指定 dialect
、dbCreate
或 jmxExport
,也不需要第二个 hibernate
块,只有创建连接池所需的信息(默认情况下会创建 10 个初始连接)。
如果您担心这种方法的额外内存(您不应该担心,它将是最小的)您可以做更多的工作并在 [=21] 中手动注册一个 Spring bean =].如果您使用的是最新版本的 Grails,数据源实现是 Tomcat JDBC Connection Pool,因此请使用其驱动程序 class 和 setter 属性 名称来指定连接信息。使用任何有效的 Spring bean 名称,但我会遵循多个数据源支持的约定:
import org.apache.tomcat.jdbc.pool.DataSource
beans = {
dataSource_drupal(DataSource) { bean ->
bean.destroyMethod = 'close'
driverClassName = '...'
url = '...'
username = '...'
password = '...'
// optional extra settings, not really needed
// unless you expect a lot of usage
initialSize = 42
testOnBorrow = true
testWhileIdle = false
testOnReturn = false
validationQuery = 'SELECT 1'
}
}
因此,要使用您的第二个数据源,请将其依赖注入到您将用于执行数据迁移工作的服务中:
def dataSource_drupal
并执行 SQL 查询,最好的选择是 groovy.sql.Sql
,因为它很好地隐藏了与 JDBC 代码相关的大部分仪式。添加导入
import groovy.sql.Sql
并创建一个新实例,将 DataSource
bean 传递给它的构造函数,以便它可以使用它来获取连接:
Sql sql = new Sql(dataSource_drupal)
sql.eachRow('select name, bar from foo' ) { row ->
Foo foo = new Foo(name: row.name, bar: row.bar)
if (!foo.save()) {
log.error "Validation error(s) for data $row: $foo.errors"
}
}