开源中国

我们不支持 IE 10 及以下版本浏览器

It appears you’re using an unsupported browser

为了获得更好的浏览体验,我们强烈建议您使用较新版本的 Chrome、 Firefox、 Safari 等,或者升级到最新版本的IE浏览器。 如果您使用的是 IE 11 或以上版本,请关闭“兼容性视图”。
把 Java 8 流解析成 SQL - 技术翻译 - 开源中国社区

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

标签: Java
oschina 推荐于 2年前 (共 5 段, 翻译完成于 12-29) 评论 35
收藏  
75
推荐标签: Java 待读

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

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

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

LeoXu
 翻译得不错哦!

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

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

LeoXu
 翻译得不错哦!

假设在远程数据库服务器上你有一张用户表,你想打印年龄大于 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
 翻译得不错哦!

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

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

wancheng
 翻译得不错哦!

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

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

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

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

wancheng
 翻译得不错哦!
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们
评论(35)
Ctrl/CMD+Enter

比C#还是弱啊
Linq 3.5 2007
这不就是hibernate 的criterial嘛。。。
criterial+1
人生苦短,我用python

引用来自“王洪旭”的评论

人生苦短,我用python
问题是你老板同意么

引用来自“王洪旭”的评论

人生苦短,我用python

引用来自“CasparLi”的评论

问题是你老板同意么
问题是不同意他会换老板
又是为敏捷开发服务的
slick
还是PHP的关联数组+SQL大道至简,不会为了OOP就DAO,也不会为了DAO就ORM,更不会为了语法糖搞什么OOP还集成仿SQL查询的不伦不类的LINQ.

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

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

引用来自“Tex”的评论

这不就是hibernate 的criterial嘛。。。
不过jpa的criteria比较丑陋。。

引用来自“eechen”的评论

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

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

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

引用来自“IdleMan”的评论

Linq 3.5 2007
哈,也想到LINQ了。

引用来自“eechen”的评论

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

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

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

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

不是所有的人都能成长到像你一样对语言如此浸淫痴迷以至于在技术的颠峰上已空前绝后,有时候应该原谅世人的平庸与无能,强求别人达到你的高度不明智,因有些人本就喜欢平庸与无能而其尤不自知。做自己的王者,让后来者在真正体会到你所言此中真意后狂热膜拜你吧
SQL+数组,多直观呀,简单压倒一切,平平淡淡才是真.倒是JAVAer,整天痴迷OOP,痴迷语法糖.看看王垠写的《编程的智慧》吧: http://www.yinwang.org/blog-cn/2015/11/21/programming-philosophy/ 并不是语言提供什么,你就一定要把它用上的。实际上你只需要其中很小的一部分功能,就能写出优秀的代码。我一向反对“充分利用”程序语言里的所有特性。实际上,我心目中有一套最好的构造。不管语言提供了多么“神奇”的,“新”的特性,我基本都只用经过千锤百炼,我觉得值得信赖的那一套。
模仿什么不好,模仿Linq这样无聊的技术,流操作的本质是利用流操作解决跨线程问题的,结果搞的和Linq一样是用来拼字符串了

引用来自“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大军切不可自乱军心,你耍PHP很牛掰,不代表Java里可以耍得出像PHP那套,跨语言对于目前的我来说,接近于找死,以前Java开发的高复用代码都要维护,待我25、26Java颠峰后再来找你一战可好,到时拳怕少壮,你已老了而我正当风华凌绝顶,定当让你汗颜,呵呵。。。
我觉得大家可以看看这篇文章http://zh.lucida.me/blog/java-8-lambdas-insideout-language-features/ 的第二部分,说明structural type的部分就可以看出为什么现在Java8现在还不能想LINQ那样操作。
sql+数组在java里还不是有现成的,spring jdbcTemplate就可以,mybatis也可以不过要写个接口。所以我最中意的开发方式是,Hibernate+jdbcTemplate混搭,开发速度贼快
为什么eechen开小号和自己长篇大段的刷屏也没个人管下。 :)

引用来自“王洪旭”的评论

人生苦短,我用python

引用来自“CasparLi”的评论

问题是你老板同意么

引用来自“雨翔河”的评论

问题是不同意他会换老板
然后失业了?
顶部