成为Java流大师–第4部分:数据库流
SQL一直是一種聲明性語言,而Java長期以來勢在必行。 Java流改變了游戲規(guī)則。 通過本動手文章編寫您的方式,并學習如何使用Java流對RDBMS數(shù)據庫執(zhí)行聲明性查詢,而無需編寫任何SQL代碼。 您會發(fā)現(xiàn),Java流和SQL命令的動詞之間有著驚人的相似性。
本文是五分之四 ,另外還有一個GitHub存儲庫,其中包含每個單元的說明和練習。
第1部分:創(chuàng)建流 第2部分:中級操作 第三部分:終端操作 第4部分:數(shù)據庫流 第5部分:使用流創(chuàng)建數(shù)據庫應用程序
當您熟悉Streams的操作時,您可能已經注意到與SQL構造的相似之處。 它們中的一些或多或少直接映射到Stream操作,例如LIMIT和COUNT 。 開源項目Speedment利用這種相似性,使用純Java提供對任何關系數(shù)據庫的類型安全訪問。
下表顯示了Speedment如何在SQL流與Java流之間進行映射。我們是Speedment開源項目的貢獻者,我們將描述Speedment如何允許我們使用數(shù)據庫作為流源,并使用來自任何數(shù)據庫表的行向管道饋送數(shù)據。
如上圖所示,Speedment將建立與數(shù)據庫的連接,然后可以將數(shù)據傳遞給應用程序。 不需要為數(shù)據庫條目編寫任何代碼,因為Speedment會分析基礎數(shù)據庫并自動生成域模型所需的所有實體類。 當您不必為要使用的每個表手動編寫和維護實體類時,它可以節(jié)省大量時間。
Sakila數(shù)據庫
為了本文和練習的方便,我們使用MySQL示例數(shù)據庫Sakila作為我們的數(shù)據源。 Sakila數(shù)據庫為老式電影租賃業(yè)務建模,因此包含諸如Film和Actor之類的表。 數(shù)據庫實例已部署在云中,并且可以公開訪問。
速度管理器
在Speedment中,數(shù)據庫表的句柄稱為
Manager 。 管理器是自動生成的代碼的一部分。
Manager充當數(shù)據庫表的句柄,并且可以充當流源。 在這種情況下,每一行都對應一個Film實例。
通過調用以下內容來實例化“加速Manager :
FilmManager films = speedment.getOrThrow(FilmManager. class );注意:speedment是可以從ApplicationBuilder獲得的實例(下一篇文章中有關此主題的更多信息)。
如果調用了FilmManager::stream ,則結果是一個Stream ,我們可以自由地對其應用任何中間或終端操作。 首先,我們將收集列表中的所有行。
List<Film> allFilms = films.stream().collect(toList()); FilmImpl { filmId = 1 , title = ACADEMY DINOSAUR, … FilmImpl { filmId = 2 , title = ACE GOLDFINGER, … FilmImpl { filmId = 3 , title = ADAPTATION HOLES, … FilmImpl { filmId = , title = ADAPTATION HOLES, … …過濾和計數(shù)
讓我們看一個簡單的示例,該示例輸出評級為“ PG-13”的電影數(shù)量。 就像常規(guī)Stream ,我們可以過濾出具有正確評分的電影,然后對這些條目進行計數(shù)。
long pg13FilmCount = films.stream() .filter(Film.RATING.equal( "PG-13" )) .count(); pg13FilmCount: 195Speedment自定義實現(xiàn)Streams后的一個重要屬性是,流能夠通過自省來優(yōu)化自己的管道。 看起來Stream會遍歷表的所有行,但事實并非如此。 相反,Speedment能夠將管道轉換為傳遞給數(shù)據庫的優(yōu)化SQL查詢。 這意味著僅將相關的數(shù)據庫條目提取到流中。 因此,在上面的示例中,類似于“ SELECT…FROM film WHERE rating ='PG-13'”,流將自動呈現(xiàn)為SQL。
這種自省要求將匿名lambda的任何使用(不包含與目標列相關的任何元數(shù)據)替換為Speedment Fields中的謂詞。 在這種情況下, Film.RATING.equal(“PG-13”)返回一個Predicate ,該Predicate將在每個Film上進行測試,并且僅當該Film的評級為PG-13時才返回true。
雖然,這并不妨礙我們將謂詞表示為:
.filter(f -> f.getRating().equals(“PG- 13 ”))但這將迫使Speedment提取表中的所有行,然后應用謂詞,因此不建議這樣做。
尋找最長的電影
這是一個使用max-operator和Field Film.LENGTH查找數(shù)據庫中最長的電影的Field Film.LENGTH :
Optional<Film> longestFilm = films.stream() .max(Film.LENGTH); longestFilm: Optional[FilmImpl {filmId = 141 , title = CHICAGO NORTH, length = 185 , ...}]尋找三部短片
找到三部短片(我們定義為短于<= 50分鐘)可以通過過濾掉50分鐘或更短的任何片并挑選出前三個結果來完成。 該示例中的謂詞查看“長度”列的值,并確定該值是否小于或等于50。
List<Film> threeShortFilms = films.stream() .filter(Film.LENGTH.lessOrEqual( 50 )) .limit( 3 ) .collect(toList()); threeShortFilms: [ FilmImpl { filmId = 2 , length = 48 ,..}, FilmImpl { filmId = 3 , length = 50 , … }, FilmImpl { filmId = 15 , length = 46 , ...}]分頁分頁
如果要在網站或應用程序中顯示所有電影,我們可能希望對項目進行分頁,而不是一次(可能)加載數(shù)千個條目。 這可以通過結合操作skip()和limit() 。 在下面的示例中,我們收集第二頁的內容,假設每個“頁面”包含25個條目。 回想一下,Streams不能保證元素的特定順序,這意味著我們需要使用sorted-operator定義一個順序才能使其按預期工作。
List<Film> filmsSortedByLengthPage2 = films.stream() .sorted(Film.LENGTH) .skip( 25 * 1 ) .limit( 25 ) .collect(toList()); filmsSortedByLengthPage2: [FilmImpl { filmId = 430 , length = 49 , …}, …] 注意:查找第n頁的內容是通過跳過(25 *(n-1))完成的。
注意2:此流將自動呈現(xiàn)為“ SELECT…FROM film ORDER BY length ASC LIMIT?”。 OFFSET?,值:[25,25]”
以“ A”開頭的電影,按長度排序
我們可以輕松地找到任何以大寫字母“ A”開頭的電影,并根據其長度(以最短的電影為首)對它們進行排序,如下所示:
List<Film> filmsTitleStartsWithA = films.stream() .filter(Film.TITLE.startsWith( "A" )) .sorted(Film.LENGTH) .collect(Collectors.toList()); filmsTitleStartsWithA: [ FilmImpl { filmId= 15 , title=ALIEN CENTER, …, rating=NC- 17 , length = 46 , FilmImpl { filmId= 2 , title=ACE GOLDFINGER, …, rating=G, length = 48 , … ]計算膠片長度的頻率表
我們還可以利用groupingBy運算符根據其長度對存儲桶中的膠片進行排序,并計算每個存儲桶中的膠片總數(shù)。 這將創(chuàng)建一個所謂的膠片長度頻率表。
Map<Short, Long> frequencyTableOfLength = films.stream() .collect(Collectors.groupingBy( Film.LENGTH.asShort(), counting() )); frequencyTableOfLength: { 46 = 5 , 47 = 7 , 48 = 11 , 49 = 5 , … }練習題
對于本周的練習,您無需擔心連接自己的數(shù)據庫。 相反,我們已經提供了到云中Sakila數(shù)據庫實例的連接。 像往常一樣,這些練習可以在此GitHub存儲庫中找到。 本文的內容足以解決名為MyUnit4Database的第四個單元。 相應的
Unit4Database接口包含JavaDocs,它們描述MyUnit4Database方法的預期實現(xiàn)。
提供的測試(例如Unit4MyDatabaseTests )將充當自動評分工具,讓您知道您的解決方案是否正確。
下一篇
到目前為止,我們僅涉及數(shù)據庫流的內容。 下一篇文章將允許您使用純Java編寫獨立的數(shù)據庫應用程序。 編碼愉快!
s
Per Minborg
Julia·古斯塔夫森(Julia Gustafsson)
資源資源
GitHub開源項目加速
Speedment Stream ORM 初始化程序
GitHub存儲庫“ hol-streams”
文章第1部分:創(chuàng)建流 第2部分:中級操作 第3部分:終端機操作
翻譯自: https://www.javacodegeeks.com/2019/11/become-a-master-of-java-streams-database-streams.html
總結
以上是生活随笔為你收集整理的成为Java流大师–第4部分:数据库流的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓声音修改器下载(安卓声音修改)
- 下一篇: java 根据类名示例化类_如何使用示例