在 Data Geekery ,我们喜欢Java。 而且,由于我们真的很喜欢 jOOQ的流畅的API和查询DSL ,我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 我们已经 写了一些关于Java 8好东西的博客 ,现在我们觉得是时候开始一个新的博客系列了……
Java 8星期五
每个星期五,我们都会向您展示一些不错的教程风格的Java 8新功能,这些功能利用了lambda表达式,扩展方法和其他好东西。 您可以在GitHub上找到源代码 。
Java 8 Goodie:Lambda和SQL
如果您习惯于编写Groovy,这对您来说可能是“ so 2003”。 我们知道。 自成立以来,Groovy便知道一种非常有用的方式来编写基于字符串的SQL。 这是用Groovy编写的示例( 请参阅此处的官方文档 ):
import groovy.sql.Sql
sql = Sql.newInstance( 'jdbc:h2:~/test', 'sa', '', 'org.h2.Driver' )
sql.eachRow( 'select * from information_schema.schemata'
) { println "$it.SCHEMA_NAME -- $it.IS_DEFAULT"
}
还要注意Groovy的内置String插值,您可以在其中将表达式放入字符串中。 但是,如果我们使用的是第三方库而不是直接使用JDBC,那么我们在Java领域,并且在Java 8中,Java / SQL集成也会变得更好。
在以下示例中,我们正在研究如何使用这三个流行的库从H2数据库中获取数据并将记录映射到自定义POJO / DTO中:
- OO (震惊,我知道)
- Spring数据/ JDBC
- Apache Commons DbUtils
与往常一样, 这些资源也可以从GitHub获得 。 对于这些测试,我们将创建一些POJO / DTO来包装模式元信息:
class Schema {final String schemaName;final boolean isDefault;Schema(String schemaName, boolean isDefault) {this.schemaName = schemaName;this.isDefault = isDefault;}@Overridepublic String toString() {return "Schema{" +"schemaName='" + schemaName + '\'' +", isDefault=" + isDefault +'}';}
}
我们的主要方法将通过DriverManager
获得H2连接:
Class.forName("org.h2.Driver");
try (Connection c = getConnection("jdbc:h2:~/test", "sa", "")) {String sql = "select schema_name, is_default "+"from information_schema.schemata "+"order by schema_name";// Library code here...
}
现在,当使用基于字符串的SQL时,Java 8如何改进jOOQ API? 太好了! 查看以下小查询:
DSL.using(c).fetch(sql).map(r -> new Schema(r.getValue("SCHEMA_NAME", String.class),r.getValue("IS_DEFAULT", boolean.class))).forEach(System.out::println);
这应该是这样,对吗? 请注意,jOOQ的本机API还能够将数据库Record
直接映射到您的POJO上,例如:
DSL.using(c).fetch(sql).into(Schema.class).forEach(System.out::println);
使用Spring JDBC和RowMapper
时,事情看起来同样不错(请注意,以下内容仍会引发已检查的SQLException
):
new JdbcTemplate(new SingleConnectionDataSource(c, true)).query(sql, (rs, rowNum) -> new Schema(rs.getString("SCHEMA_NAME"),rs.getBoolean("IS_DEFAULT"))).forEach(System.out::println);
…如果您使用的是Apache DbUtils ,则可以执行几乎相同的操作:
new QueryRunner().query(c, sql, new ArrayListHandler()).stream().map(array -> new Schema((String) array[0],(Boolean) array[1])).forEach(System.out::println);
结论
这三种解决方案或多或少都是等效的,并且非常精简。 同样,这里的要点是Java 8将改进所有现有的API。 接受SAM参数(单一抽象方法类型)的方法越明确(很少重载!),对于Java 8集成越好。
下周,我们将看到使用java.util.Map API时将大大改善的几件事。
翻译自: https://www.javacodegeeks.com/2014/02/java-8-friday-goodies-lambdas-and-sql.html