在try-with-resources块之外传输JOOQ结果时,是否存在JDBC连接泄漏的风险?

时间:2016-02-22 16:08:27

标签: java-8 java-stream jooq autocloseable

我有一个JOOQ查询,我想避免同时实现所有记录。 (但是,我可以联合实现从它们创建的所有bean对象。)

我有以下简单方法来加载数据:

public List<CustomerInfo> getCustomers() {
    return dslContext
                .selectFrom(CUSTOMER)
                // <-- note the missing .fetch()
                .stream()
                .map(CustomerInfo::new)
                .collect(Collectors.toList());
}

在任何情况下都会导致JDBC连接泄露吗? (例如CustomerInfo::new中的例外)

1 个答案:

答案 0 :(得分:6)

我已经试着找到一种方法来注册一个可靠的流“完成”钩子,它会触发完整的流消耗或任何异常,但不幸的是,这是不可能的:Register a Stream "completion" hook

所以,实际上,您显示的代码不正确。使用“懒惰”流(或Cursor)进行操作的正确方法是使用try-with-resources语句。以下两个是等效的:

// Using a Stream
try (Stream<CustomerRecord> stream = dslContext.selectFrom(CUSTOMER).stream()) {
    return stream.map(CustomerInfo::new).collect(Collectors.toList());
}

// Using a Cursor
try (Cursor<CustomerRecord> cursor = dslContext.selectFrom(CUSTOMER).fetchLazy()) {
    return cursor.stream().map(CustomerInfo::new).collect(Collectors.toList());
}

另请注意ResultQuery.stream() javadoc:

  

这与fetchLazy()基本相同,但不返回Cursor,而是返回Java 8 Stream。客户应确保Stream正确关闭,例如在try-with-resources语句中