q7goodies事例_Java 8 Friday Goodies:SQL ResultSet流

q7goodies事例

Data Geekery ,我们喜欢Java。 而且,由于我们真的很喜欢jOOQ的流畅的API和查询DSL ,我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 我们已经写了一些关于Java 8好东西的博客 ,现在我们觉得是时候开始一个新的博客系列了,……

Java 8星期五

每个星期五,我们都会向您展示一些不错的教程风格的Java 8新功能,这些功能利用了lambda表达式,扩展方法和其他出色的功能。 您可以在GitHub上找到源代码

Java 8 Goodie:SQL ResultSet流

是的,必须再次处理SQL主题。 即使上周我们答应了关于并发性的文章 ,Java 8 lambda和与“传统” API的互操作性也是一个非常重要的方面,我们首先要讨论。

检查异常

是。 不幸的是,当我们使用Java 8的lambda表达式时,过去的那些野兽仍然困扰着我们。 在Java 8发行之前,已经有几个与此主题相关的Stack Overflow问题。

让我们记住遍历文件系统时IOExceptions是如何引起问题的 。 除非您编写自己的实用程序,否则您将不得不诉诸此美:

Arrays.stream(dir.listFiles()).forEach(file -> {
    try {
        System.out.println(file.getCanonicalPath());
    }
    catch (IOException e) {
        throw new RuntimeException(e);
    }

    // Ouch, my fingers hurt! All this typing!
});

我们认为可以肯定地说:

Java 8和检查的异常不匹配。

一种解决方法是编写包装受检查的异常的自己的CheckedConsumer 。 这样的使用者将具有很高的可重用性,但是……您是否想到了所有其他FunctionalInterfacesjava.util.function包中有很多它们:

jOOλ–在Java 8中修复lambda

jool-logo-黑色 在编写这个Java 8博客系列时 ,我们经常遇到需要在lambda表达式中包装检查异常的需求。 当我们经常遇到问题时,极客会怎么做? 我们修复它! 并且我们创建了jOOλ(也是jOOL,jOO-Lambda)ASL 2.0许可的 ,在其中我们几乎复制了JDK可用的每个FunctionalInterface ,以支持受检查的异常。 在上面的示例中,使用jOOλ的方法如下:

Arrays.stream(dir.listFiles()).forEach(
    Unchecked.consumer(file -> {
        // Throw all sorts of checked exceptions
        // here, we don't care...
        System.out.println(file.getCanonicalPath());
    })
);

上面的示例显示了如何简单地忽略检查的异常并将其作为RuntimeExceptions传递。 如果您确实想处理它们,则可以传递一个异常处理程序lambda:

Arrays.stream(dir.listFiles())
      .forEach(Unchecked.consumer(

    file -> {
        System.out.println(file.getCanonicalPath());
    },
    e -> {
        log.info("Log stuff here", e);
        throw new MyRuntimeException(e);
    }
);

现在,第二个示例似乎同样冗长,但是不用担心。 您可能会重用该异常处理程序,然后回到此状态:

Arrays.stream(dir.listFiles())
      .forEach(Unchecked.consumer(
    file -> {
        System.out.println(file.getCanonicalPath());
    },
    myExceptionHandler
);

jOOλ–提供JDBC ResultSet流

不幸的是,Java 8 Streams API中的大多数工作都是在正确实现可并行化流的领域中进行的。 尽管这对于实际进行并行计算的我们来说非常有用,但对于大多数其他人而言,与遗留API更好的集成会更好。 JDBC应该值得一提的是JDBC,而我们之前已经在博客上进行了介绍 。 使用jOOλ ,您现在可以直接从ResultSets甚至从PreparedStatements生成流。 准备方法如下:

Class.forName("org.h2.Driver");
try (Connection c = getConnection()) {
    String sql = "select schema_name, is_default " +
                 "from information_schema.schemata " +
                 "order by schema_name";

    try (PreparedStatement stmt = c.prepareStatement(sql)) {
        // code here
    }
}

现在,使用jOOλ时要做的所有事情就是流这样的PreparedStatements

SQL.stream(stmt, Unchecked.function(rs ->
    new SQLGoodies.Schema(
        rs.getString("SCHEMA_NAME"),
        rs.getBoolean("IS_DEFAULT")
    )
))
.forEach(System.out::println);

其中SQLGoodies.Schema只是普通的POJO。 一些stream()方法的签名是这些签名:

public static <T> Stream<T> stream(
    PreparedStatement stmt,
    Function<ResultSet, T> rowFunction
);

public static <T> Stream<T> stream(
    PreparedStatement stmt,
    Function<ResultSet, T> rowFunction,
    Consumer<? super SQLException> exceptionHandler
);

其他也可用。

太棒了,不是吗?

JDBC ResultSet应该是Java 8流。

不幸的是,上面的代码没有将其纳入JDK 8,因为这将是一次最终极大地改善JDBC API的机会。 朱利安·艾森伯格(Julian Exenberger)在此进行了另一项类似的尝试来改善事物。

Java 8编写SQL的替代方法

我们还发布了使用Java 8和SQL替代jOOλ的几种方法: http : //www.jooq.org/java-8-and-sql

结论

尽管Java 8的lambda表达式很棒,但是新的Streams API却很不完整。 在实现上述内容时,我们必须实现自己的ResultSetIterator ,并将所有这些混乱情况写成将迭代器包装在Stream

StreamSupport.stream(
    Spliterators.spliteratorUnknownSize(
        new ResultSetIterator<>(
            supplier, 
            rowFunction, 
            exceptionTranslator
        ), 0
    ), false
);

如果只有我们能够生成有限的流 ,则不必首先编写Iterator

// Unfortunately, this method doesn't exist
Stream.generate(
    // Supplier, generating new POJOs
    () -> { 
        rs.next(); 
        return new SQLGoodies.Schema(
            rs.getString("SCHEMA_NAME"),
            rs.getBoolean("IS_DEFAULT")
        );
    },

    // Predicate, terminating the Stream
    () -> { !rs.isLast(); }
);

尽管jOOλ是一个可接受的中间解决方案,并且Guava家伙可能已经在研究如何修复其库,但这确实太糟糕了,因为Java 8缺少这种实用程序功能。

但是,我们在高度抱怨。 按照承诺,下周,我们将看到几个与并发相关的示例,请继续关注!

有关Java 8的更多信息

同时,请查看Eugen Paraschiv出色的Java 8资源页面


翻译自: https://www.javacodegeeks.com/2014/03/java-8-friday-goodies-sql-resultset-streams.html

q7goodies事例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值