我正在使用Jooq
从数据库中读取并转储文件中的记录。 我想以CSV格式转储记录,并在每条记录之间换行。我调查了Jooq Docs
并在谷歌上进行了研究,但没有找到任何帮助。Jooq
支持CSV format
但我如何将该功能合并到我的用例中。
我使用以下代码将记录转储到文件中:
SelectQuery<Record> query = getDslContext().selectQuery();
try {
@Cleanup FileOutputStream fileOutputStream = new FileOutputStream(FILE);
@Cleanup GZIPOutputStream gzipOutputStream = new GZIPOutputStream(fileOutputStream);
@Cleanup OutputStreamWriter outputStreamWriter = new OutputStreamWriter(gzipOutputStream, charsetName);
@Cleanup BufferedWriter writer = new BufferedWriter(outputStreamWriter);
@Cleanup Cursor<Record> cursor = query.fetchSize(MAX_FETCH_SIZE).fetchLazy();
while(cursor.hasNext()){
Result<Record> results = cursor.fetchNext(MAX_FETCH_SIZE);
for (Record record : results){
writer.write(record.formatJSON());
writer.newLine();
}
}
使用CSVFormat.newline()
属性:
String csv = results.formatCSV(new CSVFormat().newline("nn"));
或者,由于您是在行子集的基础上迭代光标,因此您可能还希望删除标题:
String csv = results.formatCSV(new CSVFormat().newline("nn").header(false));
这也会在末尾生成两个尾随换行符,如果不需要,您可以轻松删除它们:
csv = csv.trim();
您可以直接从Result<Record> results
设置记录的格式,而无需手动迭代每条记录。
唯一的问题是,由于您正在以MAX_FETCH_SIZE
为批次获取记录,因此每批的格式化 csv 将包含标头,您可能只需要在第一批中写入标头。
@Cleanup Cursor<Record> cursor = query.fetchSize(2).fetchLazy();
boolean includeHeaders = true;
int dataStartIndex = 0;
while(cursor.hasNext()){
Result<Record> results = cursor.fetchNext(2);
String csv = results.formatCSV();
if (includeHeaders) {
writer.write(csv);
dataStartIndex = csv.indexOf('n') + 1;
includeHeaders = false;
continue;
}
writer.write(csv.substring(dataStartIndex));
}