sql 解析 java
当Java 8发行并且人们开始流式处理各种东西时,不久之后他们就开始想象如果可以以相同的方式使用数据库将有多大的潜力。 本质上,关系数据库由以表状结构组织的巨大数据块组成。 这些结构非常适合进行过滤和映射操作,如SQL语言的SELECT,WHERE和AS语句所示。 人们最初做的事情(包括我在内)是向数据库询问大量数据,然后使用新的炫酷Java 8流处理这些数据。
很快出现的问题是,仅将所有行从数据库移到内存的等待时间就花费了太多时间。 结果是,使用内存中的数据没有太多收益。 即使您可以使用新的Java 8-tools真正搞怪高级功能,但由于性能开销,这种优势并没有真正应用到数据库应用程序中。
当我开始致力于Speedment Open Source项目时,我们很快意识到使用Java 8路数据库的潜力,但是我们确实需要一种智能的方式来处理此性能问题。 在本文中,我将向您展示我们如何使用Stream API的自定义委托人来解决此问题,以在后台处理流,并优化生成SQL查询。
假设您在远程主机上的数据库中有一个表User,而您想打印出所有70岁以上用户的名字。 使用Speedment做到这一点的Java 8方法是:
final UserManager users = speedment.managerOf(User.class);
users.stream().filter(User.AGE.greaterThan(70)).map(User.NAME.get()).forEach(System.out::println);
看到此代码可能会在一开始让您不寒而栗。 我的程序会从数据库下载整个表并在客户端中对其进行过滤吗? 如果我有1亿用户怎么办? 网络延迟足以杀死应用程序! 嗯,实际上不是,因为正如我之前所说,Speedment在终止之前会分析流。
让我们看看幕后发生的事情。 UserManager中的.stream()方法返回Stream接口的自定义实现,该接口包含有关该流的所有元数据,直到该流关闭为止。 终止操作可以使用该元数据来优化流。 调用.forEach时,管道将如下所示:
终止操作(在这种情况下,ForEach随后将开始向后遍历管道以查看是否可以优化。首先,它遇到了从User到String的映射。由于User.NAME字段,Speedment将其识别为Getter函数。可以将Getter解析为SQL,因此将终止操作切换为NAME列的Read操作,并删除map操作。
接下来是.filter操作。 过滤器也被识别为自定义操作,在这种情况下为谓词。 由于这是一个自定义实现,因此它可以包含在SQL查询中使用它所需的所有必要元数据,因此可以安全地从流中将其删除并附加到Read操作中。
现在,当终止操作查找管道时,它将找到流的源。 到达源后,将把Read操作解析为SQL并提交给SQL管理器。 然后,将使用原始的.forEach使用者终止生成的Stream <String>。 为上面显示的确切代码生成SQL是:
SELECT `name` FROM `User` WHERE `User`.`age` > 70;
Java代码中无需使用任何更改或特殊操作!
这是一个简单的示例,说明如何通过使用Speedment中的自定义实现在执行之前简化流。 欢迎您查看源代码,并找到使用此技术的更好方法。 它确实帮助我们提高了系统性能,并且可能适用于任何分布式Java-8方案。
直到下一次!
翻译自: https://www.javacodegeeks.com/2016/02/parsing-java-8-streams-sql.html
sql 解析 java