日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

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

發布時間:2023/12/3 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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對象,我們現在可以使用從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對象用于將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流制作数据透视表的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。