使用数据库中的Java流制作数据透视表

来自数据库行和表的原始数据不能为人类读者提供太多了解。 相反,如果我们对数据执行某种聚合,则人类更有可能看到数据模式
在展示给我们之前。 数据透视表是聚合的一种特定形式,我们可以在其中应用排序,求平均值或求和之类的操作,也可以对列值进行分组。

在本文中,我将展示如何在不编写SQL的情况下,可以用纯Java从数据库计算数据透视表。 您可以轻松地重用和修改本文中的示例,以满足您自己的特定需求。

在以下示例中,我使用了开源Speedment (它是Java Stream ORM)和MySQL的开源Sakila电影数据库内容。 Speedment适用于任何主要的关系数据库类型,例如MySQL,PostgreSQL,Oracle,MariaDB,Microsoft SQL Server,DB2,AS400等。

旋转

我将构造一个MapActor对象,并为每个Actor ,相应的List电影,一个特殊的电影分级的Actor出现在这里是为特定的枢轴如何进入一个例子。 Actor可能看起来像口头上表示:

“约翰·多伊(John Doe)参加了9部评级为'PG-13'的电影和4部评级为'R'的电影”。

我们将计算数据库中所有参与者的枢轴值。 Sakila数据库具有此特定应用程序感兴趣的三个表:

1)包含所有影片以及影片评级的“影片”(例如“ PG-13”,“ R”等)。
2)包含(组成)演员的“演员”(例如“ MICHAEL BOLGER”,“ LAURA BRODY”等)。
3)“电影演员”,以多对多的关系将电影和演员联系在一起。

解决方案的第一部分涉及将这三个表连接在一起。 联接是使用Speedment的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<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);

build()采用方法引用Tuples::of ,该方法引用将解析为采用三个类型的实体的构造函数; FilmActorFilmActor ,这将创建一个包含这些特定实体的复合不可变Tuple3 。 元组内置于Speedment中。

有了Join对象,我们现在可以使用从Joi​​n对象获得的标准Java Stream创建数据透视图:

Map<Actor, Map<String, Long>> pivot = join.stream().collect(groupingBy(// Applies Actor as a first classifierTuple3::get2,groupingBy(// Applies rating as second level classifiertu -> tu.get1().getRating().get(),counting() // Counts the elements )));

现在已经计算了枢轴Map ,我们可以像这样打印其内容:

// pivot keys: Actor, values: Map<String, Long>
pivot.forEach((k, v) -> { System.out.format("%22s  %5s %n",k.getFirstName() + " " + k.getLastName(),V);
});

这将产生以下输出:

MICHAEL BOLGER  {PG-13=9, R=3, NC-17=6, PG=4, G=8} LAURA BRODY  {PG-13=8, R=3, NC-17=6, PG=6, G=3} CAMERON ZELLWEGER  {PG-13=8, R=2, NC-17=3, PG=15, G=5}
...

任务完成! 在上面的代码中,方法Tuple3::get2将从元组( Actor )中检索第三个元素,而方法tu.get1()将从元组( Film )中检索第二个元素。

Speedment将自动从Java渲染SQL代码,并将结果转换为Java Stream。 如果启用流日志记录,我们可以确切看到如何呈现SQL:

SELECT A.`actor_id`,A.`film_id`,A.`last_update`, B.`film_id`,B.`title`,B.`description`,B.`release_year`,B.`language_id`,B.`original_language_id`,B.`rental_duration`,B.`rental_rate`,B.`length`,B.`replacement_cost`,B.`rating`,B.`special_features`,B.`last_update`, C.`actor_id`,C.`first_name`,C.`last_name`,C.`last_update`
FROM `sakila`.`film_actor` AS A
INNER JOIN `sakila`.`film` AS B ON (B.`film_id` = A.`film_id`) 
INNER JOIN `sakila`.`actor` AS C ON (C.`actor_id` = A.`actor_id`)

加入自定义元组

正如我们在上面的示例中所注意到的,由于在连接阶段仅将FilmActor对象用于将FilmActor实体链接在一起,因此在Stream中没有实际使用FilmActor对象。 此外,通用Tuple3有一般get0() get1()get2()是没有说他们装的是什么东西的方法。

所有这些都可以通过定义我们自己的称为ActorRating的自定义“元组”来ActorRating如下所示:

private static class ActorRating {private final Actor actor;private final String rating;public ActorRating(FilmActor fa, Film film, Actor actor) {// fa is not used. See below whythis.actor = actor;this.rating = film.getRating().get();}public Actor actor() {return actor;}public String rating() {return rating;}}

当使用build()方法build() Join对象时,我们可以提供一个自定义构造函数,该构造函数要应用于数据库的传入实体。 这是我们将要使用的功能,如下所示:

Join<ActorRating> join = joinComponent.from(FilmActorManager.IDENTIFIER).innerJoinOn(Film.FILM_ID).equal(FilmActor.FILM_ID).innerJoinOn(Actor.ACTOR_ID).equal(FilmActor.ACTOR_ID).build(ActorRating::new); // Use a custom constructorMap<Actor, Map<String, Long>> pivot = join.stream().collect(groupingBy(ActorRating::actor,groupingBy(ActorRating::rating,counting())));

在此示例中,我们证明了带有构造函数的类(方法参考ActorRating:new被解析为new ActorRating(fa, actor, film) ),该FilmActor函数只是完全丢弃了链接的FilmActor对象。 该类还为其属性提供了更好的名称,这使代码更具可读性。 使用自定义ActorRating类的解决方案将产生与第一个示例完全相同的输出结果,但使用时看起来要好得多。 我认为在大多数情况下,与使用通用元组相比,编写自定义元组值得付出额外的精力。

使用平行旋转

Speedment的一件很酷的事情是,它支持开箱即用的Stream方法parallel() 。 因此,如果您的服务器具有许多CPU,则在运行数据库查询和联接时可以利用所有这些CPU内核。 这就是并行枢轴的样子:

Map<Actor, Map<String, Long>> pivot = join.stream().parallel()  // Make our Stream parallel.collect(groupingBy(ActorRating::actor,groupingBy(ActorRating::rating,counting())));

我们只需要添加一行代码即可进行并行聚合。 当我们达到1024个元素时,将启动默认的并行拆分策略。 因此,并行枢转将仅在大于此值的表或联接上进行。 应该注意的是,Sakila数据库仅包含1000部电影,因此我们必须在更大的数据库上运行代码才能真正受益于并行性。

试试看!

在本文中,我们展示了如何在不编写任何SQL代码的情况下,就可以使用Java从数据库计算数据透视表。 访问GitHub上的 Speedment开源以了解更多信息。

在《用户指南》中阅读有关其他功能的更多信息。

翻译自: https://www.javacodegeeks.com/2018/05/making-pivot-tables-with-java-streams-from-databases.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/346714.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java map的keyset_Java Map keySet()用法及代码示例

此方法用于返回此映射中包含的键的Set视图。该集合由Map支持&#xff0c;因此对Map的更改会反映在集合中&#xff0c;反之亦然。用法:Set keySet()参数&#xff1a;此方法没有参数。返回值&#xff1a;此方法返回一个包含指定映射键的集合。下面的程序显示int keySet()方法的实…

asynchttpclient 超时_dnf这才是混子的毕业套装,却发现超时空漩涡不买账!

dnf这才是混子的毕业套装&#xff0c;却发现超时空漩涡不买账&#xff01;按道理来说&#xff0c;光兵和帕拉丁穿这套装备去混团是最好的&#xff0c;结果现在超时空漩涡不要&#xff01;虽然说兵法套是95最好的魂之涛&#xff0c;但是这个混子套属性真心弱爆&#xff0c;不如正…

统计多维数组php_PHP多维数组中统计元素个数

Array([0] > Array([0] > Array([0] > Array([id] > 12[name] > 1)[1] > Array([id] > 28[name] > 2).....)[1] > Array([0] > Array([id] > 121[name] > 2)[1] > Array([id] > 281[name] > 4)...))....)我想统计name对应的值出现…

mongodb web_MongoDB和Web应用程序

mongodb web当今时代是数据以非常大的速度增长的时代。 数据存储不是问题&#xff0c;是的&#xff0c;但是它的结构化和存储方式可能会增加或减少所需数据块的查找时间。 不断增长的非结构化数据的用例 脸书&#xff1a; 活跃用户达7.5亿&#xff0c;互联网用户中有三分之一…

win7亮度怎么调_揭秘极米NEW Z8X投影仪怎么样?千万不要上当?!!!!【揭秘反馈

反馈测评极米NEW Z8X投影仪怎么样?求真实点评注意事项极米NEW Z8X投影仪怎么样?靠谱真实回答 外形外观&#xff1a;简约时尚大气&#xff0c;手感不错&#xff01;\n投影亮度&#xff1a;1080P、4K&#xff0c;都能做到&#xff01;\n投影色彩&#xff1a;非常好&#xff0c;…

php的完整代码块,简单测试了一下php中的代码块、内部类等知识

简单测试了一下php中的代码块、内部类等知识<?php class a{public $b;public function print_result(){//普通代码块&#xff0c;但已经不是java中的代码块{$c变量;echo 普通代码块&#xff1f;;}echo $c;}//错误的语法&#xff0c;Parse error: syntax error, unexpected …

Paw 百度ai_直面落地!百度EasyDL产业智能创新大赛成果覆盖能源、交通、水利民生重业...

物体检测模型实现高压线路隐患检测、图像分类实现短视频快速剪辑和量产、文本情感分类辅助潜在心理疾病患者自发检测、图片识别车辆轮轴数监管车辆载重……每一个创想都能简单快速实现&#xff0c;没有AI开发基础的小伙伴们也能做到&#xff01;这一切都缘于百度零门槛AI开发平…

Java 9、10及更高版本:Java平台的未来

您紧跟Java平台新功能的秘密武器 自去年9月发布Java 9以来&#xff0c;感觉整个平台都经历了重大变化。 在我们甚至无法确定Java 9所能提供的一切之前&#xff0c;我们已经在标记Java 10的发布。现在&#xff0c;我们已经开始期待Java 11在2018年9月发布。 Oracle决定为Java平…

php同时抢购 代码,浅谈PHP实现大流量下抢购方案

要求要有小时分钟秒的实时倒计时的显示&#xff0c;用户端修改日期时间不会影响到倒计时的正常显示(也就是以服务器时间为准)。其实这和很多的考试等系统的时间限制功能同样的要求。总不能用ajax每秒都获取服务器时间吧&#xff0c;所以实时倒计时一定要用javascript实现。这很…

c fread 快读 详解_奔驰ACC(自适应巡航系统)详解

什么是ACC自适应巡航&#xff1f;ACC自适应巡航( Adaptive Cruise Control )&#xff0c;又可称为智能巡航控制系统&#xff0c;简称ACC系统&#xff0c;它是在传统巡航控制基础上发展起来的新一代汽车驾驶员辅助驾驶系统。它将汽车自动巡航控制系统CCS 和车辆前向撞击报警系统…

php使用邮件找回密码,php利用Zend_Mail发送邮件(实现邮件重设密码功能)

[php]代码库<?php include_once conn/conn.php;require_once Zend/Mail.php;//调用发送邮件的文件require_once Zend/Mail/Transport/Smtp.php;//调用SMTP验证文件$reback 0;$name $_GET[foundname];$question $_GET[question];$answer $_GET[answer];$sql "sele…

_Linux 最常用命令整理,建议收藏!

Linux是目前应用最广泛的服务器操作系统&#xff0c;基于Unix&#xff0c;开源免费&#xff0c;由于系统的稳定性和安全性&#xff0c;市场占有率很高&#xff0c;几乎成为程序代码运行的最佳系统环境。linux不仅可以长时间的运行我们编写的程序代码&#xff0c;还可以安装在各…

openjdk 使用_如何在OpenJDK中使用ECC

openjdk 使用曾经试图在Java和OpenJDK中使用椭圆曲线密码术 &#xff08;ECC&#xff09;的每个人要么被迫使用Bouncy Castle&#xff0c;要么被SunEC提供者弄糊涂了 。 SunEC提供程序根据文档 &#xff08;报价&#xff09;提供以下算法&#xff1a; AlgorithmParameters 欧…

bpcs uploader.php,linux 备份定时同步到百度云盘

导读&#xff1a;现在的百度云盘免费容量都是2T了&#xff0c;即便把电脑上全部的东东都放上去&#xff0c;也还有大把的剩余空间。对于站长来讲&#xff0c;是彻底能够充分利用这些硬盘空间的&#xff0c;如今咱们就用百度云盘来备份Linux服务器上的数据。php一直在想&#xf…

hadoop可以解决什么问题_快速解决皮带机轴磨损问题可以这样做

皮带机是皮带输送机的简称&#xff0c;皮带机运用输送带的连续或间歇运动来输送各种轻重不同的物品&#xff0c;既可输送各种散料&#xff0c;也可输送各种纸箱、包装袋等单件重量不大的件货&#xff0c;用途广泛。皮带机运行时轴磨损是一个很常见的设备问题&#xff0c;某企业…

matlab 从 excel读取 日期_毕业季:计量经济学实证研究中,哪款软件好(SPSS,Eviews,Matlab,stata,SAS)...

毕业季&#xff1a;计量经济学实证研究中&#xff0c;哪款软件好&#xff1f;&#xff08;SPSS&#xff0c;Eviews&#xff0c;Matlab&#xff0c;stata&#xff0c;SAS&#xff09;对于这个问题&#xff0c;我也深深的迷茫过。用了包括但不限于Excel、SPSS、SPSS modeler、Evi…

php 猴子选大王,php猴子选大王

法一&#xff1a;function monkeyKing($n,$m){$arrrange(1,$n);$i0;while (count($arr)>1){for($i1;$i<$m-1;$i){array_push($arr, array_shift($arr));}array_shift($arr);}echo "$arr[0]";}monkeyKing(6,4);//5法二&#xff1a;function king($m ,$n){//构造…

java 队列和堆栈_Java中的堆栈和队列

java 队列和堆栈我最近一直在研究一些需要堆栈和队列的Java代码。 使用的选择不是立即显而易见的。 有一个Queue接口&#xff0c;但没有明确的具体实现要使用。 还有一个Stack类&#xff0c;但是javadocs指出其他类“应该优先于此类使用”。 那么&#xff0c;您对Java中的堆栈和…

dbassit 包_CELINE新包,篮子包、圆盒包、腋下包、托特包等

CELINE 2021春夏女装系列以纪录片形式发布&#xff0c;由创意总监 Hedi Slimane 执导并设计配乐&#xff0c;在摩纳哥路易二世体育场取景。CELINE 2021春夏时装秀本季作品以「一代人的肖像」为题&#xff0c;在复古优雅中融入富有街头感的运动元素。CELINE 2021春夏时装秀女孩们…

Php数组面包屑导航,php可应用于面包屑导航的迭代寻找家谱树实现方法

php是通过定义类来实现迭代器接口来构造迭代器&#xff0c;通过yield构造迭代器可以提高性能并节省系统开销&#xff0c;下面就跟着爱站技术频道小编的步伐来学习php可应用于面包屑导航的迭代寻找家谱树实现方法吧。具体实现方法如下&#xff1a;echo "";$area arra…