java导出数据透视表_使用数据库中的Java流制作数据透视表
java导出数据透视表
来自数据库行和表的原始数据不能为人类读者提供太多了解。 相反,如果我们对数据执行某种聚合,则人类更有可能看到数据模式
在向我们展示之前。 数据透视表是聚合的一种特定形式,我们可以在其中应用排序,求平均值或求和之类的操作,也可以对列值进行分组。
在本文中,我将展示如何在不编写SQL的情况下就可以从纯Java数据库中计算数据的数据透视表。 您可以轻松地重用和修改本文中的示例,以满足您自己的特定需求。
在以下示例中,我使用了开源Speedment (它是Java Stream ORM)和MySQL的开源Sakila电影数据库内容。 Speedment适用于任何主要的关系数据库类型,例如MySQL,PostgreSQL,Oracle,MariaDB,Microsoft SQL Server,DB2,AS400等。
旋转
我将构造一个Map
的Actor
对象,并为每个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
,该方法引用将解析为采用三个类型的实体的构造函数。 FilmActor
, Film
和Actor
,这将创建一个包含这些特定实体的复合不可变Tuple3
。 元组内置于Speedment中。
有了Join对象,我们现在可以使用从Join对象获得的标准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
对象用于将Film
和Actor
实体链接在一起,因此我们在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
java导出数据透视表
java导出数据透视表_使用数据库中的Java流制作数据透视表相关推荐
- 下面选项中属于java基本数据类型的有_下面选项中属于Java基本数据类型的有
[单选题]以下选项哪个不是指导学生学会接受的策略运作要点? [判断题]瓢虫的种类非常繁多,我们可以从它们的颜色上加以区别,也可以根据它们的体型来区别. [简答题]紧定螺钉联接有何特点? [单选题]在客 ...
- mysql 数据透视_把数据库中的数据制作成Excel数据透视表
如果我们在使用Excel的时候,需要把数据库中的数据制作成Excel数据透视表,我们该怎么操作呢?如果数据在数据库中,我们不用把数据导入到工作表中,我们可以直接以数据库的全部数据或者部分数据制作数据透 ...
- mysql 查询不为0的数据_查询数据库中所有记录总数不为0的数据表名称
[如何查询postgreSQL 里面某个数据库中所有用户定义的数据表的名字@forandever 2011-11-131.通过命令行查询\d 数据库 -- 得到所有表的名字\d 表名 -- 得到表 ...
- excel查询mysql数据库表,excel创建数据表/查询mysql数据库中所有表名
excel两个表格,数据库表与专门查询该数据库信息的表.在查询表中以多个项目进行查询符合条件的数据. 可以用"筛选"这个功能,在菜单里,对两个列进行筛选,符合条件的就会显示出来.很 ...
- 数据库表设计、 数据库分层、myslq水平拆分、oracle表分区
数据库表设计 数据库表结构设计方法及原则(li)数据库设计的三大范式:为了建立冗余较小.结构合理的数据库,设计数据库时必须遵循一定的规则.在关系型数据库中这种规则就称为范式.范式是符合某一种设计要求的 ...
- 如何将excel表导入oracle数据库,如何将EXCEL表导入ORACLE数据库中?【转】
来源:https://zhidao.baidu.com/question/383828330.html?qbl=relate_question_2&word=excel%20%B1%ED%CA ...
- java跨库join方案_集算器协助java处理多样性数据源之跨库关联
Java的数据计算类库RowSet提供了JoinRowSet和FilteredRowSet类,可以进行跨库的关联计算,但是有很多局限.首先,JoinRowSet只支持inner join,不支持out ...
- mysql 修复表字段_mysql数据库总结一【安装,配置,表操作,字段操作,增删改, 备份-恢复,select查询】...
服务器端安装 安装服务器端:在终端中输入如下命令,回车后,然后按照提示输入 sudo apt-get install mysql-server 启动服务 sudo service mysql star ...
- Oracle数据库中调用Java类开发存储过程、函数的方法
Oracle数据库中调用Java类开发存储过程.函数的方法 时间:2014年12月24日 浏览:5538次 oracle数据库的开发非常灵活,不仅支持最基本的SQL,而且还提供了独有的PL/SQL, ...
最新文章
- 同是程序员,为什么别人可以事半功倍?
- Androidstudio如何正确导入和移出jar包
- erlang精要(5)-列表推导式
- vue的基本项目结构
- 技术交流:老刘说NLP技术公众号开通
- Evernote是什么软件?印象笔记for mac V10.3.6官方版
- (软件工程复习核心重点)第一章软件工程概论-第一节:软件和软件危机
- Python_爬虫_案例汇总:
- utilities(matlab)—— minFunc
- nvm切换node版本的命令
- 浏览器edge插件的安全与个人隐私
- 动态指针时钟:利用pyqt5制作指针钟表显示实时时间
- Todd Lammle's CCNA IOS Commands Survival Guide
- GBase 8s分布式功能之异地容灾
- 通过日期的相减计算年龄
- 5个人站队,每个人不在原位置有多少种站法
- 2014年10月23日(账本软件)
- Learning Angular 学习Angular Lynda课程中文字幕
- 华罗庚统筹法与计算机专业,华罗庚的优选法与统筹法
- 8、数值分析与matlab
热门文章
- 牛客题霸 [括号序列] C++题解/答案
- AT2005-[AGC003E]Sequential operations on Sequence【差分,思维】
- P3599-Koishi Loves Construction【构造,数论】
- P3850-[TJOI2007]书架【Splay】
- P3807-[模板]卢卡斯定理
- 图解HashMap和HashSet的内部工作机制
- springboot+mybatis-plus实例demo
- MyBatis中增删改操作
- 2017蓝桥杯省赛---java---A---2(9数算式)
- 2015蓝桥杯省赛---java---B---3(三羊献瑞)