当我在 90 年代后期编写我的第一个 Java 数据库应用程序时,我必须自己做所有事情。有很多代码、错误捕获和对象转换正在进行,代码很快变得非常难以维护,而且我不得不承认,容易出错。
即使在今天,当您使用数据库时,在面向对象语言(如 Java)和关系数据库这两个根本不同的世界之间架起桥梁也常常很麻烦。通常,您需要编写自己的映射层,或者您可以使用像 Hibernate 这样的对象关系映射器 (ORM)。使用 ORM 通常很方便,但有时以正确的方式配置它并不那么容易。通常情况下,ORM 还会减慢您的应用程序。
最近,我一直在为一个名为 Speedment 的新开源项目做出很多贡献,我们的贡献者希望这个项目能让我们 Java 8 数据库应用程序开发人员的生活更轻松。
什么是 Speedment 开源?
Speedment Open Source 是一个新的库,它提供了许多有趣的 Java 8 特性。它从一开始就完全用 Java 8 编写。 Speedment 使用标准的 Streams 来查询数据库,因此,您不必学习任何新的查询 API。您根本不必考虑 JDBC、ResultSet 和其他数据库特定的事情。
Speedment 分析现有数据库并自动生成代码。这样,您不必为数据库实体编写一行代码。生成的代码甚至包含自动生成的 JavaDocs。这意味着您不必在 Java 代码中编写诸如“User”或“Book”之类的实体类。相反,您只需创建一个(或使用现有的)数据库,将 Speedment 连接到它,Speedment 将分析数据库结构并通过分析数据库结构生成实体类。
因为 Speedment 的开源吉祥物是一只野兔,所以我在我的许多示例中都使用了野兔。假设我们有一个名为“hare”的现有 (MySQL) 表,如下所示:
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):
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)
我将在另一篇文章中解释 find*() 方法。它们可以用来代替 SQL 连接。
查询
以下是查询 Hare 表时的示例:
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)
智能流
现在,上面的代码看起来会遍历“hare”数据库表中的所有行,但实际上不会。 Stream 是“聪明的”,在到达其 终端操作 collect() 时,将分析过滤器谓词并得出结论,它实际上是与 8 进行比较的“hare.age”列,因此,它将能够减少野兔流到对应于“从年龄 > 8 的野兔中选择 *”的东西。如果您使用多个过滤器,它们当然会进一步组合以进一步减少流。
只是为了说明原理,这里是另一个操作更多的流:
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)
当此 Stream 达到其 Terminal Operation count() 时,它将检查自己的管道。然后它将得出结论,它可以像前面的示例一样减少 AGE 谓词。它还将进一步得出结论,操作 mapToInt() 和 sorted() 不会改变 count() 的结果,因此,这些操作可以一起消除。所以该语句简化为“select count(*) from hare where age > 8”。
这意味着您可以使用 Java 8 流,而不必太在意流如何转换为 SQL。
如何下载和贡献
在 www.speedment.org 上阅读更多关于 Speedment Open Source 的信息,如果您想了解更多信息,例如 API 的外观以及如何在您的项目中使用 Speedment,那么这里就是您的最佳去处。 Speedment 在 GitHub 上 。您可以通过 在 gitter 上 提交评论或下载源代码并使用您自己的代码贡献创建拉取请求来做出贡献。
结论
回顾我在 Java 时代初期的一些旧项目,我的一个数据库类(超过 100 行)现在可以减少到一行 Java 8 代码。那是摩尔定律,但是倒过来了!在 14 年(=7 个摩尔周期)中,行数减半约 7 倍。那就是进步!