Speedment是一个Java Stream ORM工具包和运行时,它使您可以将数据库表作为标准Java Streams查看。 由于不必混合使用Java和SQL,因此该应用程序变得更加紧凑,从而使其开发速度更快,更不容易出错并且更易于维护。 流也严格地是类型安全的,并且是惰性构造的,因此当元素被流消耗时,仅从数据库中提取最小量的数据。

现在,新版本的Speedment 3.1.1“ Homer”还支持将动态联接的表视为标准Java Streams。 开发开发数据库表之间关系的Java应用程序时,这很重要。

在下面的示例中,我使用了MySQL的开源Sakila电影数据库内容,您可以在此处下载。 Speedment适用于任何主要的关系数据库类型,例如Oracle,MySQL,Microsoft SQL Server,PostgreSQL,DB2,MariaDB,AS400等。

在单个表上流式传输

以下代码段将创建一个所有Film.RATING为“ PG-13”的Film对象的List ,并且该List按Film.LENGTH顺序排序:

List<Film> list = films.stream().filter(Film.RATING.equal("PG-13")).sorted(Film.LENGTH).collect(toList());

该流将在后台自动呈现给SQL查询。 如果启用流日志记录,我们将看到以下内容(准备好的语句“?”-变量最后以值形式给出):

SELECT `film_id`,`title`,`description`,`release_year`,`language_id`,`original_language_id`,`rental_duration`,`rental_rate`,`length`,`replacement_cost`,`rating`,`special_features`,`last_update`
FROM `sakila`.`film`
WHERE (`rating`  = ? COLLATE utf8_bin)
ORDER BY`length` ASCvalues:[PG-13]

因此,优点是您可以使用类型安全的Java表示数据库查询,然后通过标准Java流使用结果。 您不必编写任何SQL代码。

连接几张桌子

从“电影”表的Appart来看,Sakila数据库还包含其他表。 其中之一是称为“语言”的表。 每个Film实体都使用名为“ language_id”的列来为电影中使用的Language指定外键。

在此示例中,我将展示如何创建代表这两个表的联接的标准Java Stream。 这样,我们可以获得匹配的Film/Language实体对的Java流。

Join对象是使用JoinComponent创建的,可以通过以下方式获得:

// Visit https://github.com/speedment/speedment
// to see how a Speedment app is created. It is easy!
Speedment app = …;JoinComponent joinComponent = app.getOrThrow(JoinComponent.class);

抓住JoinComponent ,就可以开始创建Join对象,如下所示:

Join<Tuple2<Film, Language>> join = joinComponent.from(FilmManager.IDENTIFIER).innerJoinOn(Language.LANGUAGE_ID).equal(Film.LANGUAGE_ID).build(Tuples::of);

现在我们已经定义了Join对象,我们可以创建实际的Java Stream:

join.stream().map(t2 -> String.format("The film '%s' is in %s",t2.get0().getTitle(), // get0() -> Filmt2.get1().getName()   // get1() -> Language)).forEach(System.out::println);

这将产生以下输出:

The film 'ACADEMY DINOSAUR' is in English
The film 'ACE GOLDFINGER' is in English
The film 'ADAPTATION HOLES' is in English
...

在上面的代码中,方法t2.get0()将从元组( Film )检索第一个元素,而方法t2.get1()将从元组( Language )检索第二个元素。 默认通用元组内置在Speedment中,因此Tuple2不是Guava类。 速度不依赖于任何其他库。 在下面,您将看到如何为连接的表使用任何类构造函数。 同样,Speedment将自动从Java渲染SQL代码,并将结果转换为Java Stream。 如果启用流日志记录,我们可以确切看到如何呈现SQL代码:

SELECTA.`film_id`,A.`title`,A.`description`,A.`release_year`,A.`language_id`,A.`original_language_id`,A.`rental_duration`,A.`rental_rate`,A.`length`,A.`replacement_cost`,A.`rating`,A.`special_features`,A.`last_update`,B.`language_id`,B.`name`,B.`last_update`
FROM `sakila`.`film` AS A
INNER JOIN `sakila`.`language` AS B
ON(B.`language_id` = A.`language_id`)

有趣的是,可以创建一次Join对象,然后反复使用它来创建新的Streams。

多对多关系

Sakila数据库还定义了少数多对多关系。 例如,表“ film_actor”包含将影片链接到演员的行。 每部电影可以有多个演员,并且每个演员可能都出现在多部电影中。 表格中的每一行都将特定的Film链接到特定的Actor 。 例如,如果Film描述了12个Actor entities, then FilmActor包含12个条目,它们均具有相同的film_id但具有不同的actor_id。 本示例的目的是创建Java Stream中所有电影和现身演员的完整列表。 这是我们如何将三个表连接在一起的方法:

Join<Tuple3<FilmActor, Film, Actor>> join = joinComponent.from(FilmActorManager.IDENTIFIER).innerJoinOn(Film.FILM_ID).equal(FilmActor.FILM_ID).innerJoinOn(Actor.ACTOR_ID).equal(FilmActor.ACTOR_ID).build(Tuples::of);join.stream().forEach(System.out::println);

上面的代码将产生以下输出(为便于阅读而设置格式):

...
Tuple3Impl {FilmActorImpl { actorId = 137, filmId = 249, lastUpdate = 2006-02-15 05:05:03.0 },FilmImpl { filmId = 249, title = DRACULA CRYSTAL, description =...,ActorImpl { actorId = 137, firstName = MORGAN, lastName = WILLIAMS,...}
}Tuple3Impl {FilmActorImpl { actorId = 137, filmId = 254, lastUpdate = 2006-02-15 05:05:03.0 },FilmImpl { filmId = 254, title = DRIVER ANNIE, description = ...,ActorImpl { actorId = 137, firstName = MORGAN, lastName = WILLIAMS, ...}
}Tuple3Impl {FilmActorImpl { actorId = 137, filmId = 263, lastUpdate = 2006-02-15 05:05:03.0 },FilmImpl { filmId = 263, title = DURHAM PANKY, description = ... },ActorImpl { actorId = 137, firstName = MORGAN, lastName = WILLIAMS,... }
}
...

加入自定义元组

正如我们在上面的例子中注意到,我们没有实际使用的FilmActor在Stream对象,因为它只是用来连接FilmActor在加入阶段对象在一起。

当使用build()方法build() Join对象时,我们可以提供一个自定义构造函数,该构造函数要应用于数据库的传入实体。 构造函数可以是任何类型,因此您可以编写自己的Java对象,该对象包含例如FilmActor或它们包含的并且感兴趣的任何列。

在此示例中,我证明了(lambda)构造函数只是完全丢弃了链接的FilmActor对象:

Join<Tuple2<Film, Actor>> join = joinComponent.from(FilmActorManager.IDENTIFIER).innerJoinOn(Film.FILM_ID).equal(FilmActor.FILM_ID).innerJoinOn(Actor.ACTOR_ID).equal(FilmActor.ACTOR_ID).build((fa, f, a) -> Tuples.of(f, a));join.stream().forEach(System.out::println);

上面的代码将产生以下输出(为便于阅读而设置格式):

...
Tuple2Impl {FilmImpl { filmId = 249, title = DRACULA CRYSTAL, description = ... },ActorImpl { actorId = 137, firstName = MORGAN, lastName = WILLIAMS, ...}
}
Tuple2Impl {FilmImpl { filmId = 254, title = DRIVER ANNIE, description = A... }, ActorImpl { actorId = 137, firstName = MORGAN, lastName = WILLIAMS,...}
}
Tuple2Impl {FilmImpl { filmId = 263, title = DURHAM PANKY, description = ... }, ActorImpl { actorId = 137, firstName = MORGAN, lastName = WILLIAMS,...}
}
...

因此,我们只会在Film中存在Actor下,获得匹配的FilmActor实体对。 在流中永远不会看到链接对象FilmActor

试试看!

在本文的整个过程中,您学习了如何使用Speedment流处理一个或几个数据库表。

访问GitHub上的 Speedment开源并尝试一下!

阅读《用户指南》中有关新的JOIN功能的所有信息。

翻译自: https://www.javacodegeeks.com/2018/05/java-stream-orm-now-with-joins.html

Java Stream ORM现在带有JOIN相关推荐

  1. java orm框架有哪些_Java Stream ORM现在带有JOIN

    java orm框架有哪些 Speedment是一个Java Stream ORM工具包和运行时,它使您可以将数据库表作为标准Java Streams查看. 由于不必混合使用Java和SQL,因此该应 ...

  2. Java Stream:第2部分,计数始终是计数吗?

    在上一篇有关该主题的文章中 ,我们了解到JDK 8 stream()::count需要更长的时间来执行Stream更多的元素. 对于较新的JDK(例如Java 11),简单流管道不再是这种情况. 了解 ...

  3. java peek函数_基础篇:JAVA.Stream函数,优雅的数据流操作

    写在开头:本文是转载于掘金上的一篇文章,已获得原作者授权,我会在文章最后放上原作者和原文链接. 前言 平时操作集合数据,我们一般都是for或者iterator去遍历,不是很好看.java提供了Stre ...

  4. Spring ORM示例 - 带有AOP事务管理

    Spring ORM示例 - 带有AOP事务管理 这是一个非常简单的Spring ORM示例,向您展示如何使用Spring配置应用程序 依赖注入(@Autowired annotation), JPA ...

  5. mycat集群执行带有join的sql语句时报错_can‘t find table define in schema_分片join---Linux运维工作笔记052

    这里要注意了,如果你在mycat中执行一个带有join关键字的,sql语句,如果报错了的话 ,上面的错误,原因就是,你在mycat中配置的时候,应该是没有配置ER表, ER表,会把具有,主表,子表关系 ...

  6. Java 代码写的又臭又长,还不会用 Java Stream 函数式编程?

    点击上方"猿芯",选择"设为星标" 后台回复"1024",有份惊喜送给面试的你 原文 https://www.cnblogs.com/Car ...

  7. Java Stream流的使用

    Stream流--Java8新特性之一 用于处理集合,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找.过滤和映射数据等操作. Java Steam的操作是基于集合的.Steam的操作可以分为 ...

  8. [源码解析] 当 Java Stream 遇见 Flink

    [源码解析] 当 Java Stream 遇见 Flink 文章目录 [源码解析] 当 Java Stream 遇见 Flink 0x00 摘要 0x01 领域 1.1 Flink 1.2 Java ...

  9. Java-Runoob:Java Stream、File、IO

    ylbtech-Java-Runoob:Java Stream.File.IO 1.返回顶部 1. Java 流(Stream).文件(File)和IO Java.io 包几乎包含了所有操作输入.输出 ...

最新文章

  1. linux mysql 2003错误代码,如何解决linux mysql2003错误
  2. OVS packet处理流程(三十二)
  3. Java常用类之String类练习
  4. 算法与数据结构(python):冒泡排序、选择排序、插入排序
  5. Java.io.File.getPath()方法实例
  6. 庄小威、陈志坚等9位科学家分享2100万美元奖金:2019年科学突破奖公布
  7. java开发 时间类型的转换
  8. shell给python传变量_python和shell 传递变量
  9. C++调用V8与JS交互
  10. python3闭包通俗解释_python通俗解说闭包
  11. 《哈佛大学幸福课》笔记
  12. 《如何有效阅读一本书-超实用笔记读书法》
  13. Responses 部分 | Http Header
  14. java中BigDecimal求余
  15. MIT6.828学习之homework2:shell
  16. Windows直接拖拽文件复制到虚拟机Ubuntu
  17. stm32+k210视觉小车——来拒去留+多位串口通信
  18. JavaScript如何截取字符串的最后一位
  19. C语言每日一练——第80天:换分币问题
  20. 【弹性布局】【设置主轴,交叉轴对齐方式】

热门文章

  1. 动态规划训练24 [Phalanx HDU - 2859 ]
  2. 34、JAVA_WEB开发基础之EL表达式和标签
  3. Sentinel(十五)之在生产环境中使用 Sentinel
  4. Java面试,如何在短时间内做突击
  5. 汇编语言(十)之最小偶数
  6. JavaFX UI控件教程(三)之Label
  7. Oracle入门(十三)之SQL的DML
  8. Vue之splice和push
  9. 好玩的Scratch
  10. mysql预编译语句拼接查询_SQL语句预编译(查询)