gpt4 book ai didi

sql - Grails - 存储将由服务使用的 sql

转载 作者:行者123 更新时间:2023-12-04 22:15:15 25 4
gpt4 key购买 nike

我正在编写一个主要使用 springws web services plugin 的 Grails 应用程序端点由服务支持。这些服务将从各种后端数据库中检索数据(即,不通过域类和 GORM)。我想存储我的服务将用于在外部文件中获取 Web 服务数据的 sql。我正在寻找以下方面的建议:

  1. 保存文件的最佳位置(即,我想将它们放在明显的地方,如 grails-app/sql)和最佳格式(即,xml、configslurper 等)

  2. 抽象 sql 文本检索的最佳方式,这样我将执行 sql 的服务将不需要知道它们是从何处获取或如何获取的。服务将只提供一个 sqlid 并获取 sql。

最佳答案

我最近在做一个项目,我需要做类似的事情。我创建了以下目录来存储 sql 文件:

./grails-app/conf/sql

例如,有一个文件 ./grails-app/conf/sql/hr/FIND_PERSON_BY_ID.sql 包含如下内容:

select a.id
, a.first_name
, a.last_name
from person
where id = ?

我创建了一个 SqlCatalogService 类,它将加载该目录(和子目录)中的所有文件并将文件名(减去扩展名)和文件文本存储在 Map 中。该服务有一个 get(id) 方法,该方法返回缓存在 Map 中的 sql 文本。由于存储在grails-app/conf中的文件/目录都放在类路径中,SqlCatalogService使用以下代码读入文件:

....
....
Map<String,String> sqlCache = [:]
....
....
void loadSqlCache() {
try {
loadSqlCacheFromDirectory(new File(this.class.getResource("/sql/").getFile()))
} catch (Exception ex) {
log.error(ex)
}
}

void loadSqlCacheFromDirectory(File directory) {
log.info "Loading SQL cache from disk using base directory ${directory.name}"
synchronized(sqlCache) {
if(sqlCache.size() == 0) {
try {
directory.eachFileRecurse { sqlFile ->
if(sqlFile.isFile() && sqlFile.name.toUpperCase().endsWith(".SQL")) {
def sqlKey = sqlFile.name.toUpperCase()[0..-5]
sqlCache[sqlKey] = sqlFile.text
log.debug "added SQL [${sqlKey}] to cache"
}
}
} catch (Exception ex) {
log.error(ex)
}
} else {
log.warn "request to load sql cache and cache not empty: size [${sqlCache.size()}]"
}
}
}

String get(String sqlId) {
def sqlKey = sqlId?.toUpperCase()
log.debug "SQL Id requested: ${sqlKey}"
if(!sqlCache[sqlKey]) {
log.debug "SQL [${sqlKey}] not found in cache, loading cache from disk"
loadSqlCache()
}
return sqlCache[sqlKey]
}

使用各种数据源的服务使用 SqlCatalogService 通过调用 get(id) 方法检索 sql:

class PersonService {

def hrDataSource
def sqlCatalogService

private static final String SQL_FIND_PERSON_BY_ID = "FIND_PERSON_BY_ID"

Person findPersonById(String personId) {
try {
def sql = new groovy.sql.Sql(hrDataSource)
def row = sql.firstRow(sqlCatalogService.get(SQL_FIND_PERSON_BY_ID), [personId])
row ? new Person(row) : null
} catch (Exception ex) {
log.error ex.message, ex
throw ex
}
}
}

目前我们只有几个 sql 语句,因此将所有文本存储在 Map 中不是问题。如果要存储大量的 sql 文件,您可能需要考虑使用类似 Ehcache 的东西并定义驱逐策略(即,最近最少使用或最不经常使用)并且仅将最常用的存储在内存中并将其余的保留在磁盘上直到需要.

在做这件事之前,我考虑过使用 GORM 并将 sql 文本存储在数据库中。但是决定将 sql 放在文件中使得开发更容易,因为我们几乎可以直接从我们的 sql 工具将 sql 保存到文件(用问号替换硬编码参数)并且能够让我们的版本控制系统跟踪变化。我并不是说上述服务是处理此问题的最有效或最正确的方法,但到目前为止它已满足我们的需求。

关于sql - Grails - 存储将由服务使用的 sql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1352650/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com