Java8中使用流方式查询数据库的方法


由于关系型数据库操作语言和面向对象语言之间的差异,如今我们仍然需要花费许多时间建立数据库与 Java 应用之间互相沟通的桥梁。通常,我们可以编写自己的映射层(mapping layer),或者使用第三方的 ORM(Object Relational Mapper)对象关系映射框架,比如 Hibernate。ORM 框架虽然使用起来很方便,但是如何正确地配置和提高框架操作数据库的性能却不太容易,ORM 框架往往会使我们的应用性能下降。 最近,我贡献了一个新的开源项目——Speedment,它能使我们使用 Java 8 开发数据库应用程序变得更为快捷和高效。

Speedment 是使用 ORM 方式操作数据库的一种选择,以前我们需要100行操作数据库的 Java 代码,在 Java 8中,可能只需要一行代码。

在90年代末,我使用 Java 开发数据库应用的时候,许多代码逻辑都需要自己来编写,比如捕获异常、类型转换等,经过许多改动,最后这些代码变得难以维护和扩展。

由于关系型数据库操作语言和面向对象语言之间的差异,如今我们仍然需要花费许多时间建立数据库与 Java 应用之间互相沟通的桥梁。通常,我们可以编写自己的映射层(mapping layer),或者使用第三方的 ORM(Object Relational Mapper)对象关系映射框架,比如 Hibernate。ORM 框架虽然使用起来很方便,但是如何正确地配置和提高框架操作数据库的性能却不太容易,ORM 框架往往会使我们的应用性能下降。

最近,我贡献了一个新的开源项目——Speedment,它能使我们使用 Java 8 开发数据库应用程序变得更为快捷和高效。

Speedment 是什么?

Speedment 是一个开源项目,它是一个基于 Java 8 的新特性开发的新的 Java 库,从这个项目开发开始,它的代码就全部使用 Java 8来编写。Speedment 使用标准流查询数据库,这使得开发者不需要学习任何新的查询 API ,以及不必考虑 JDBC 、ResultSet 和其他有关数据库的指定的操作。

Speedment 会根据现有数据库来自动生成代码。由于它的这种方式,开发者不需要编写一行关于数据库实体(database entities)的代码。它生成的代码中也包含 JavaDocs 帮助文档,这使开发者不需要编写关于 User 或者 Book 等对象的实体类。取而代之地,我们只需要创建或者使用一个现有的数据库,然后用 Speedment 去连接它,接着 Speedment 会分析数据库结构来生成实体类的代码。

更有趣的是,Speedment 用野兔来作为它的吉祥物。 在接下来的例子中,我们会使用一个名为 “hare” 的数据库来给大家演示 Speedment 的使用方式。该数据库的表结构如下:

mysql> explain hare;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(45) | NO | | NULL | |
| color | varchar(45) | NO | | NULL | |
| age | int(11) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.01 sec)

下面是 Speedment 根据数据库信息生成的一个相应的实体类(为简洁起见,我们将 JavaDocs 在这里移除了):

public interface Hare extends Entity<Hare> {
public final static ReferenceComparableField<Hare, Integer> ID = new ReferenceComparableFieldImpl<>("id", Hare::getId, Hare::setId);
public final static ReferenceComparableStringField<Hare> NAME = new ReferenceComparableStringFieldImpl<>("name", Hare::getName, Hare::setName);
public final static ReferenceComparableStringField<Hare> COLOR = new ReferenceComparableStringFieldImpl<>("color", Hare::getColor, Hare::setColor);
public final static ReferenceComparableField<Hare, Integer> AGE = new ReferenceComparableFieldImpl<>("age", Hare::getAge, Hare::setAge);
Integer getId();
String getName();
String getColor();
Integer getAge();
Hare setId(Integer id);
Hare setName(String name);
Hare setColor(String color);
Hare setAge(Integer age);
/** Graph-like traversal methods eliminating JOINs */
Stream<Carrot> findCarrotsByOwner();
Stream<Carrot> findCarrotsByRival();
Stream<Carrot> findCarrots();
}

我将用一篇单独的文章介绍 find*() 方法的用法,它可以被用来代替 SQL joins 操作。

Queries查询示例

下面的例子展示如何查询 Hare 表的数据库信息:

List<Hare> oldHares = hares.stream()
.filter(AGE.greaterThan(8))
.collect(toList());

智能流

上面的代码看起来已经遍历了 hare 数据库表的所有行,但实际上并不是这样的。 Stream 是智能的,当它到达 collect() 操作的时候,会分析 filter 操作,并推断出 hare.age 大于8的列,因此会节省 hares 的流操作,产生与 “select * from hare where age > 8” 操作一样的效果。如果你使用了多个 filters,他们会被合并起来以节省流操作。下面是另一种用流方式进行多个操作的例子:

long noOldHares = hares.stream()
.filter(AGE.greaterThan(8))
.mapToInt(Hare::getAge)
.sorted()
.count();

在上面的代码中,当流到达 count() 操作时,它将检查它自己的管道。首先会推断上面例子中的 AGE 操作,其次在不改变 count() 结果的情况下,会推断 mapToInt() 和 sorted() 操作,这些操作可以被消除,因此这段代码的操作被节省为 “select count(*) from hare where age > 8”。这意味着您可以使用 Java 8 流而你不必如此在意流是如何转换为SQL的。

如何下载和加入我们

如果你想学习如何使用 Speedment 的 API 和在项目中如何使用 Speedment,可以访问网址 www.speedment.org,并可以在 gitter 上发表评论,也可以从 GitHub 上下载 Speedment 的源码,来贡献你自己的代码。

总结

回顾早期的一些老项目,一个超过100行代码的数据库类,现在可以使用 Java 8 缩减成1行代码。那是反转后的摩尔定律,在14年内(=7摩尔周期),行数大约减半了七次。这就是进步!

什么是数据流

流代表从支持聚合操作源的序列的对象。以下是数据流的特点。

元素序列 - 流提供了一组特定类型的以顺序方式元素。流获取/计算需求的元素。它不存储元素。

源- 流使用集合,数组或I/O资源为输入源。

聚合操作 - 数据流支持如filter, map, limit, reduced, find, match等聚合操作。

管道传输 - 大多数流操作的返回流本身使他们的结果可以被管道传输。这些操作被称为中间操作以及它们的功能是利用输入,处理输入和输出返回到目标。collect()方法是终端操作,这是通常出现在管道传输操作结束标记流的结束。

自动迭代 - 流操作内部做了反复对比,其中明确迭代需要集合提供源元素。



相关阅读:
thinkphp的CURD和查询方式介绍
使用JavaScript实现旋转的彩圈特效
Angularjs 基础入门
Win10 th2正式版首个重大更新普遍性Bug 开机速度超慢
Ajax实现无闪烁定时刷新页面实例代码
Java中使用异或语句实现两个变量的互换
Bootstrap每天必学之面板
linux新手学习之Arch Linux入门经验分享
Win10斯巴达浏览器集成的微软小娜使用方法
Javascript基于对象三大特性(封装性、继承性、多态性)
input:checkbox多选框实现单选效果跟radio一样
C#使用SQLDMO操作数据库的方法
php无限极分类实现的两种解决方法
PHP获取一个字符串中间一部分字符的方法
快速导航
PHP MySQL HTML CSS JavaScript MSSQL AJAX .NET JSP Linux Mac ASP 服务器 SQL jQuery C# C++ java Android IOS oracle MongoDB SQLite wamp 交通频道 作文范文 最新端午节幽默短信大全 本无心,何来心碎 我的家乡枣树美 魔鬼季节作文700字 在傻女孩身上看到的一个家庭 放在心里,淡淡相处 自由与幸福 我给弟弟讲故事 交通运输局党总支“三严三实”专题民主生活会情况汇报 寒假复活读后感 站在心灵的十字路口 学骑自行车的启示300字 科技课真有趣 小学四年级作文400字:恼人的电话铃 三年级上学期语文教学工作计划 感动的十天 水是故乡甜 青年文摘2011年第21期在线阅读 深圳打工生涯(一) 观看《让党旗更鲜艳》的心得体会 你不要担心 只是、季节的童话作文650字 我和孤儿200字 那是一个冬天 黛色第六章-晚宴 心伤,只有你能治! 护士转正自我鉴定范文2015 观察大蒜作文450字 军训心得作文1000字 春节的年味为什么越来越淡? 睡前的故事 小学五年级作文600字:空中大战 No road of flowers leads to glory. //英文励志名言警句 高中高三作文1500字:海 有关写新年的回忆作文:新年里的回忆 小学五年级作文650字:友 情 的 分 量 2015毕业生党员思想汇报 初中初一作文1200字:走在充满美的校道上 邀请函英文格式 大学生实习决心书_决心书 小学五年级作文450字:珍爱生命 拒绝毒品 散文随笔:另一样的风景 关于团队精神的名言名句 关于建设节约型机关的意见 念孔明赋作文200字 药丸与糖果 世界上最感人的话-感动的一句话 搓麻将与“黄石的孩子” 我多想为你 秋之赋作文450字

Copyright © 2016 phpStudy |