Java 在单列下将1GB文件的内容流式传输到sqlite表

Java 在单列下将1GB文件的内容流式传输到sqlite表,java,sql,jdbc,jooq,clob,Java,Sql,Jdbc,Jooq,Clob,下面的实现给出了大小为1 GB、堆空间为4 GB的文件的内存不足错误。Files.lines将返回一个流,但在运行收集器时返回。加入它会导致堆错误 我们可以使用保留原始行分隔符的jooq和jdbc来流式传输内存占用较少的文件吗 Stream<String> lines = Files.lines(path); dsl.createTable(TABLE1) .column(COL1, SQLDataType.CLOB) .column

下面的实现给出了大小为1 GB、堆空间为4 GB的文件的内存不足错误。Files.lines将返回一个流,但在运行收集器时返回。加入它会导致堆错误

我们可以使用保留原始行分隔符的jooq和jdbc来流式传输内存占用较少的文件吗

Stream<String> lines = Files.lines(path);

dsl.createTable(TABLE1)
            .column(COL1, SQLDataType.CLOB)
            .column(COL2, SQLDataType.CLOB)
            .execute();

dsl.insertInto(TABLE1)
                .columns(COL1, COL2)
                .values(VAL1, lines
                        .collect(Collectors.joining(System.lineSeparator())))
                .execute();

jOOQ针对CLOB数据类型的默认数据类型绑定将CLOB类型视为普通字符串,适用于中小型LOB。对于较大的LOB,JDBCAPI的流式版本更合适。理想情况下,您可以创建自己的数据类型绑定,从而优化流的写入操作:

例如:

类StreamingLobBinding实现绑定{ ... @凌驾 公共无效setBindingSetStatementContext ctx{ //理想情况下:在某处注册输入流以进行显式资源管理 ctx.1声明 .setBinaryStreamctx.index,新文件InputStreamCTX.value; } } 然后,您可以将此绑定应用于您的列,并让代码生成器按照上述链接中的说明提取该绑定,或者仅将其应用于单一用途:

DataType fileType=COL2.getDataType.asConvertedDataTypenew StreamingLobBinding; Field fileCol=DSL.fieldCOL2.getName,文件类型; dsl.insertIntoTABLE1 .columnscl1,fileCol .valuesVAL1,DSL.valtheFile,文件类型 处决 请注意,目前,您可能需要在一些ThreadLocal中注册输入流,以记住它并在语句执行后将其清除。未来的jOOQ版本将提供SPI来处理以下问题:

由于sqlite jdbc使用setBinaryStream抛出SQLFeatureNotSupportedException,因此还有一种方法,如上面的github问题所建议的

dsl.insertInto(TABLE1)
        .columns(TABLE1.COL1, TABLE1.COL2)
        .values("ABB", null)
        .execute();

BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
StringBuilder lines = new StringBuilder();
int bytesCount = 0;
String line = null;
int value = 0;
Field<String> coalesce = DSL.coalesce(TABLE1.COL2, "");
char[] buffer = new char[100 * 1000 * 1000];

while ((value = reader.read(buffer)) != -1) {
    lines.append(String.valueOf(buffer, 0, value));
    bytesCount += lines.length();
    if (bytesCount >= 100 * 1000 * 1000) {

        dsl.update(TABLE1).set(TABLE1.COL2, DSL.concat(coalesce, lines.toString())).where(TABLE1.COL1.eq("ABB")).execute();
        bytesCount = 0;
        lines.setLength(0);
    }
}

if (lines.length() > 0) {
   dsl.update(TABLE1).set(TABLE1.COL2, DSL.concat(coalesce, lines.toString())).where(TABLE1.COL1.eq("ABB")).execute();
}
reader.close();
dsl.insertInto(TABLE1)
        .columns(TABLE1.COL1, TABLE1.COL2)
        .values("ABB", null)
        .execute();

BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
StringBuilder lines = new StringBuilder();
int bytesCount = 0;
String line = null;
int value = 0;
Field<String> coalesce = DSL.coalesce(TABLE1.COL2, "");
char[] buffer = new char[100 * 1000 * 1000];

while ((value = reader.read(buffer)) != -1) {
    lines.append(String.valueOf(buffer, 0, value));
    bytesCount += lines.length();
    if (bytesCount >= 100 * 1000 * 1000) {

        dsl.update(TABLE1).set(TABLE1.COL2, DSL.concat(coalesce, lines.toString())).where(TABLE1.COL1.eq("ABB")).execute();
        bytesCount = 0;
        lines.setLength(0);
    }
}

if (lines.length() > 0) {
   dsl.update(TABLE1).set(TABLE1.COL2, DSL.concat(coalesce, lines.toString())).where(TABLE1.COL1.eq("ABB")).execute();
}
reader.close();