Java Stream ORM现在带有JOIN
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對象,因為它只是用來連接Film和Actor在加入階段對象在一起。
當使用build()方法build() Join對象時,我們可以提供一個自定義構造函數,該構造函數要應用于數據庫的傳入實體。 構造函數可以是任何類型,因此您可以編寫自己的Java對象,該對象包含例如Film和Actor或它們包含的并且感興趣的任何列。
在此示例中,我證明了(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下,獲得匹配的Film和Actor實體對。 在流中永遠不會看到鏈接對象FilmActor 。
試試看!
在本文的整個過程中,您學習了如何使用Speedment流處理一個或幾個數據庫表。
訪問GitHub上的 Speedment開源并嘗試一下!
閱讀《用戶指南》中有關新的JOIN功能的所有信息。
翻譯自: https://www.javacodegeeks.com/2018/05/java-stream-orm-now-with-joins.html
總結
以上是生活随笔為你收集整理的Java Stream ORM现在带有JOIN的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux如何运行c文件(linux如何
- 下一篇: 勇者斗恶龙安卓版一共几部(勇者斗恶龙安卓