把 Java 8 流解析成 SQL 已翻译 100%

oschina 投递于 2015/12/28 19:03 (共 5 段, 翻译完成于 12-29)
阅读 7425
收藏 75
3
加载中

当我们尝试用“Java 8 的方式”使用数据库时,如何去解决性能上的问题呢?

通过与 ZeroTurnaround 合作,我们为你带来了 Java Zone。你可以阅读这里的 8 个步骤的指南,来看看如何在编写代码时,利用跳过缓慢的应用程序重新部署的过程和实现应用程序分析来提高你的生产力吧!

Java 8 被发布的时候,人们开始让所有的东西变成流,没过多久他们就开始想象,如果可以将同样的方式用在数据库上,那将会有多棒。本质上数据库就是由大型的数据块以类似于表格的结构组织而成的。如 SQL 的 SELECT,WHERE,和 AS 语句向我们所表明的,这些结构对于过滤和映射操作很理想。(我们曾总结出)人们首先做的就是去向数据库获取到一个大型的数据集合,而后使用 Java8 中又新又酷的流技术来对这种数据进行处理。

LeoXu
LeoXu
翻译于 2015/12/28 20:17
1

有个问题立马就出现了,这个问题就是将来自数据库中的所有数据行转移到数据库中,其延时太长了。后果就是没能有多少盈余留下来对内存中的数据进行处理。即使你可以使用 Java 8 中新的工具做一些真正令人惊讶的东西出来,但这种好处却因为性能的消耗过甚而并不适用于数据库应用程序。

当我开始想 Speedment 开源项目做贡献是,很快就意识到用 Java 8 的方式利用数据库的潜力,不过我们确实需要一个聪明的方式来处理性能问题。在本文中我会向你展示如何使用自定义的 Stream API 代理,在后台操作一个流,对于 SQL 查询的结果进行优化,以解决这个问题。

LeoXu
LeoXu
翻译于 2015/12/28 20:26
1

假设在远程数据库服务器上你有一张用户表,你想打印年龄大于 70 岁的用户名字。 在 Java 8 中使用 Speedment 可能会是这样:

final UserManager users = speedment.managerOf(User.class);
users.stream()
    .filter(User.AGE.greaterThan(70))
    .map(User.NAME.get())
    .forEach(System.out::println);

看你这些代码你不仅要先打一个冷颤,我的程序会从数据库下载整个数据表,然后在客户端做过滤吗?如果我有 100,000,000 个用户会发生什么?网络延迟足以杀死应用程序!哇噢,事实并不是这样,就像我前面说过的。Speedment 在结束前会分析流。  

让我们来看看幕后发生了什么。UserManager 中的方法 .stream() 会返回一个流接口的自定义实现,包含流的所有无数据一直到流关闭,元数据可以被终止的事件使用以优化流。当方法 .forEach 被调用时,管道看起来会是这样: 

wancheng
wancheng
翻译于 2015/12/28 21:27
1

终止活动(在这个例子中 ForEach 将会向后遍历管道,看看它是否可以优化,首先它遇到从 User 到 String 的映射。Speedment 识别出它是一个 Getter 函数,User.NAME 字段是使用它来生成。Getter 可以解析到 SQL,所以终止活动切换到读操作,因为 NAME 列和映射被移除。 

接着是 .filter。filter 也被识别出是一个自定义操作,在这个例子中是一个谓词。因为它是一个自定义实现,它可以包含 SQL 查询中需要的所有元数据,所以可以安全地从流中移除并附加在写操作)

wancheng
wancheng
翻译于 2015/12/29 09:11
1

此时终止活动继续查找管道,它会发现流的源头,一旦到达流的源头,读操作会解析到 SQL 并提交到 SQL 管理系统。最后 Stream<String> 会被最被的 .forEach 终止掉。上面的内容会生成确切的 SQL:

SELECT `name` FROM `User` WHERE `User`.`age` > 70;

Java 代码不需要改变和特殊的操作!

这是一个简单的例子,演示了流在执行前 Speedment 如何使用一个自定义实现使它简化。欢迎你查看 the source code 寻找更好的办法来优化这个技术。它真的帮助我们改善了系统性能,并在可以在 Java-8 的任何分布式环境下工作。 

wancheng
wancheng
翻译于 2015/12/29 09:21
1
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(35)

f
fanspace
看起来挺像linq的啊,这个不错,怎么和springmvc集成?
坏小孩_99
坏小孩_99

引用来自“一只小桃子”的评论

sql+数组在java里还不是有现成的,spring jdbcTemplate就可以,mybatis也可以不过要写个接口。所以我最中意的开发方式是,Hibernate+jdbcTemplate混搭,开发速度贼快
+1
吴海宏
吴海宏
再这么玩下去我就不会写java了..
ApacheCN飞龙
ApacheCN飞龙
在web开发中,orm就是第一生产力。ioc不是所有业务都需要,模板也完全可以分离到前端去。但是orm是必需的,拼接sql带来的可读性和可维护性都很差。

别说linq to sql那种东西了,java的框架里面找个像django那种链式查询的都没有,别说带闭包的查询了。
ApacheCN飞龙
ApacheCN飞龙

引用来自“eechen”的评论

还是PHP的关联数组+SQL大道至简,不会为了OOP就DAO,也不会为了DAO就ORM,更不会为了语法糖搞什么OOP还集成仿SQL查询的不伦不类的LINQ.

查询结果很大时,PHP可以使用MYSQLI_USE_RESULT无缓冲查询,细水长流,逐条从MySQL获取,避免PHP进程占用大量的内存.

http://my.oschina.net/eechen/blog/591426

引用来自“百世经纶之傲笑红尘”的评论

不是所有的人都能成长到像你一样对语言如此浸淫痴迷以至于在技术的颠峰上已空前绝后,有时候应该原谅世人的平庸与无能,强求别人达到你的高度不明智,因有些人本就喜欢平庸与无能而其尤不自知。做自己的王者,让后来者在真正体会到你所言此中真意后狂热膜拜你吧

引用来自“eechen”的评论

SQL+数组,多直观呀,简单压倒一切,平平淡淡才是真.倒是JAVAer,整天痴迷OOP,痴迷语法糖.看看王垠写的《编程的智慧》吧: http://www.yinwang.org/blog-cn/2015/11/21/programming-philosophy/ 并不是语言提供什么,你就一定要把它用上的。实际上你只需要其中很小的一部分功能,就能写出优秀的代码。我一向反对“充分利用”程序语言里的所有特性。实际上,我心目中有一套最好的构造。不管语言提供了多么“神奇”的,“新”的特性,我基本都只用经过千锤百炼,我觉得值得信赖的那一套。
java恰恰相反。我们平时用到的东西java却没有很好的封装,于是只能“语法不足架构补”,不知道你有没有听说这个词。
wuyiw
wuyiw
012345[6][7][8][9]
\[0\]\[1\]\[2\]\[3\]\[4\]\[5\]\[6\]\[7\]\[8\]\[9\]
\\[0\\]\\[1\\]\\[2\\]\\[3\\]\\[4\\]\\[5\\]\\[6\\]\\[7\\]\\[8\\]\\[9\\]
看看表情
zigzagroad
zigzagroad

引用来自“eechen”的评论

@zigzagroad PHP中的数组不区分数字数组和关联数组(HashMap),这就是弱类型的好处,非常灵活.

引用来自“zigzagroad”的评论

从数组中取值时,如果是用索引下标取值的话就会存在顺序问题;如果不是那么就还好

引用来自“eechen”的评论

比如mysqli_stmt::get_result获得result,然后mysqli_result::fetch_all(MYSQLI_BOTH)拿到的数字索引MYSQLI_NUM和字段名索引MYSQLI_ASSOC两种数组.接下来就是如何操作数组进行输出,没有额外过多的映射关系,就是简简单单地写SQL操作数组,PHP数组操作是PHP的精髓.
JavaScript也是弱类型的,但数组也是用索引下标取值,所以是存在顺序问题的。如 var arr = new Array('aa', 'bb', 'cc', 'dd'); alert( arr ); 则提示的是 cc
eechen
eechen

引用来自“eechen”的评论

@zigzagroad PHP中的数组不区分数字数组和关联数组(HashMap),这就是弱类型的好处,非常灵活.

引用来自“zigzagroad”的评论

从数组中取值时,如果是用索引下标取值的话就会存在顺序问题;如果不是那么就还好
比如mysqli_stmt::get_result获得result,然后mysqli_result::fetch_all(MYSQLI_BOTH)拿到的数字索引MYSQLI_NUM和字段名索引MYSQLI_ASSOC两种数组.接下来就是如何操作数组进行输出,没有额外过多的映射关系,就是简简单单地写SQL操作数组,PHP数组操作是PHP的精髓.
zigzagroad
zigzagroad

引用来自“eechen”的评论

@zigzagroad PHP中的数组不区分数字数组和关联数组(HashMap),这就是弱类型的好处,非常灵活.
从数组中取值时,如果是用索引下标取值的话就会存在顺序问题;如果不是那么就还好
eechen
eechen
@百世经纶之傲笑红尘 我也只是PHP菜,我只是根据自己所见所闻和实践,得出自己的看法,并不是高手.
返回顶部
顶部