如何使用Groovy StreamingJsonBuilder将SQL结果流式传输到JSON?

如何使用Groovy StreamingJsonBuilder将SQL结果流式传输到JSON?,sql,groovy,streaming,Sql,Groovy,Streaming,我正在尝试执行一个SQL查询,并将结果转换为JSON,如下所示。虽然我在没有流媒体的情况下工作,但在使用StreamingJsonBuilder流媒体结果时遇到了一些问题 非流式代码 def writer = new StringWriter() def jsonBuilder = new StreamingJsonBuilder(writer) sql.eachRow("select * from client"){ row -> jsonBuilder( id: row.id

我正在尝试执行一个SQL查询,并将结果转换为JSON,如下所示。虽然我在没有流媒体的情况下工作,但在使用
StreamingJsonBuilder
流媒体结果时遇到了一些问题

非流式代码

def writer = new StringWriter()
def jsonBuilder = new StreamingJsonBuilder(writer)
sql.eachRow("select * from client"){ row -> 
    jsonBuilder( id: row.id, name: row.name )
}
println writer.toString()
{"id":123,"name":"ABCD"}{"id":124,"name":"NYU"}
上述代码的结果

def writer = new StringWriter()
def jsonBuilder = new StreamingJsonBuilder(writer)
sql.eachRow("select * from client"){ row -> 
    jsonBuilder( id: row.id, name: row.name )
}
println writer.toString()
{"id":123,"name":"ABCD"}{"id":124,"name":"NYU"}
这个结果的问题是,所有文档都打印在同一行上,没有定界。如何将结果作为一个数组,并将每个文档打印如下

预期结果

[
   {
      id: 123,
      name: "ABCD",
      ...
   }, 
   {
      id: 124,
      name: "NYU",
      ...
   }, 
]

我无法访问任何SQL进行尝试,但以下代码应该可以完成这项工作(您需要替换数据变量):

更新(在@cfrick的评论之后)

这里,每一行都是一行接一行地处理的,但需要一个键(在本例中是数据)

import groovy.json.*

def writer = new StringWriter()
def jsonBuilder = new StreamingJsonBuilder(writer)
def data = [
   [id:1, name: 'n1', other: 'o1'],
   [id:2, name: 'n2', other: 'o2']
]
def root = jsonBuilder(data: [])
data.each { d ->
    root.data << [id:d.id, name: d.name]
}

println(JsonOutput.prettyPrint(JsonOutput.toJson(root)))
import groovy.json*
def writer=new StringWriter()
def jsonBuilder=新StreamingJsonBuilder(编写器)
def数据=[
[id:1,名称:'n1',其他:'o1'],
[id:2,名称:'n2',其他:'o2']
]
def root=jsonBuilder(数据:[])
data.each{d->

root.data我在这里更多地将此作为一种退路。如果您的问题只是将数据正确地格式化为json,但数据量太大,使您不得不使用流API,那么您最好使用流式处理数据,并自己处理“数组”

StreamingJsonBuilder中的所有调用都会获取一个对象并直接将其写入写入写入器。因此,没有安全的方法(我可以看到)让写入器打开数组,然后以您提供的数据块发送数据,然后关闭数组。因此,既然我们已经拥有写入器,为什么不自己处理数组呢(json的这一部分很容易理解):

新文件('/tmp/out.json')。withWriter{writer->

作者:但如果你先收集整个内容,这不是真的违背了流媒体生成器的目的吗?可能不会,但是我不知道如何在不指定键的情况下从
JsonBuilder
获取简单列表。如果你知道如何做,请随意编辑这个问题。预打印工作提供了整个llection保存在内存中。但是,
StreamingJsonBuilder
没有将任何内容流式传输到
编写器
。考虑到数据的大小,我可以放弃漂亮的打印,但不能流式传输。没有流式传输到
编写器
?使用哪种解决方案?使用第一种解决方案,所有内容都应该立即写入。在第二,每个记录都应该直接写入
编写器
。我采用了第二种解决方案,添加了
println writer.toString()
。它只打印
{“数据”:[]}
@cfrick,为提供的链接添加一些说明始终是一个好主意。@cfrick,我之所以要寻找JSON对象数组,是因为我正在尝试导出关系数据并准备一个JSON文件,以便可以轻松地将其导入NoSQL数据库。因此,安全性对我来说不是一个问题。无论如何,感谢链接。