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

java导出数据透视表

java导出数据透视表_使用数据库中的Java流制作数据透视表相关推荐

  1. 下面选项中属于java基本数据类型的有_下面选项中属于Java基本数据类型的有

    [单选题]以下选项哪个不是指导学生学会接受的策略运作要点? [判断题]瓢虫的种类非常繁多,我们可以从它们的颜色上加以区别,也可以根据它们的体型来区别. [简答题]紧定螺钉联接有何特点? [单选题]在客 ...

  2. mysql 数据透视_把数据库中的数据制作成Excel数据透视表

    如果我们在使用Excel的时候,需要把数据库中的数据制作成Excel数据透视表,我们该怎么操作呢?如果数据在数据库中,我们不用把数据导入到工作表中,我们可以直接以数据库的全部数据或者部分数据制作数据透 ...

  3. mysql 查询不为0的数据_查询数据库中所有记录总数不为0的数据表名称

    [如何查询postgreSQL 里面某个数据库中所有用户定义的数据表的名字@forandever 2011-11-131.通过命令行查询\d 数据库  -- 得到所有表的名字\d 表名  -- 得到表 ...

  4. excel查询mysql数据库表,excel创建数据表/查询mysql数据库中所有表名

    excel两个表格,数据库表与专门查询该数据库信息的表.在查询表中以多个项目进行查询符合条件的数据. 可以用"筛选"这个功能,在菜单里,对两个列进行筛选,符合条件的就会显示出来.很 ...

  5. 数据库表设计、 数据库分层、myslq水平拆分、oracle表分区

    数据库表设计 数据库表结构设计方法及原则(li)数据库设计的三大范式:为了建立冗余较小.结构合理的数据库,设计数据库时必须遵循一定的规则.在关系型数据库中这种规则就称为范式.范式是符合某一种设计要求的 ...

  6. 如何将excel表导入oracle数据库,如何将EXCEL表导入ORACLE数据库中?【转】

    来源:https://zhidao.baidu.com/question/383828330.html?qbl=relate_question_2&word=excel%20%B1%ED%CA ...

  7. java跨库join方案_集算器协助java处理多样性数据源之跨库关联

    Java的数据计算类库RowSet提供了JoinRowSet和FilteredRowSet类,可以进行跨库的关联计算,但是有很多局限.首先,JoinRowSet只支持inner join,不支持out ...

  8. mysql 修复表字段_mysql数据库总结一【安装,配置,表操作,字段操作,增删改, 备份-恢复,select查询】...

    服务器端安装 安装服务器端:在终端中输入如下命令,回车后,然后按照提示输入 sudo apt-get install mysql-server 启动服务 sudo service mysql star ...

  9. Oracle数据库中调用Java类开发存储过程、函数的方法

    Oracle数据库中调用Java类开发存储过程.函数的方法 时间:2014年12月24日  浏览:5538次 oracle数据库的开发非常灵活,不仅支持最基本的SQL,而且还提供了独有的PL/SQL, ...

最新文章

  1. 同是程序员,为什么别人可以事半功倍?
  2. Androidstudio如何正确导入和移出jar包
  3. erlang精要(5)-列表推导式
  4. vue的基本项目结构
  5. 技术交流:老刘说NLP技术公众号开通
  6. Evernote是什么软件?印象笔记for mac V10.3.6官方版
  7. (软件工程复习核心重点)第一章软件工程概论-第一节:软件和软件危机
  8. Python_爬虫_案例汇总:
  9. utilities(matlab)—— minFunc
  10. nvm切换node版本的命令
  11. 浏览器edge插件的安全与个人隐私
  12. 动态指针时钟:利用pyqt5制作指针钟表显示实时时间
  13. Todd Lammle's CCNA IOS Commands Survival Guide
  14. GBase 8s分布式功能之异地容灾
  15. 通过日期的相减计算年龄
  16. 5个人站队,每个人不在原位置有多少种站法
  17. 2014年10月23日(账本软件)
  18. Learning Angular 学习Angular Lynda课程中文字幕
  19. 华罗庚统筹法与计算机专业,华罗庚的优选法与统筹法
  20. 8、数值分析与matlab

热门文章

  1. 牛客题霸 [括号序列] C++题解/答案
  2. AT2005-[AGC003E]Sequential operations on Sequence【差分,思维】
  3. P3599-Koishi Loves Construction【构造,数论】
  4. P3850-[TJOI2007]书架【Splay】
  5. P3807-[模板]卢卡斯定理
  6. 图解HashMap和HashSet的内部工作机制
  7. springboot+mybatis-plus实例demo
  8. MyBatis中增删改操作
  9. 2017蓝桥杯省赛---java---A---2(9数算式)
  10. 2015蓝桥杯省赛---java---B---3(三羊献瑞)