設計一個自動從數據庫里面分片讀取數據的流

需求定義

? ? ? 1,通常需要從數據庫里面擼出來一大片數據,一次數據庫io會很耗時導致超時,

? ? ? 2,檢索出符合條件的數據,但是僅僅依靠數據庫里面的記錄還無法判定是否符合條件,必須通過外部服務獲取相關的信息來判斷。

實現思路

? ? ?如果我們能夠將數據庫里面的記錄做成一個流,那么上面的問題將很容易解決,前者只需要使用limit()就可以獲得需要的記錄條數,后者加一個filter函數也很容易過濾掉。那么如果將一個遠端的數據源里面的數據做成一個流,又不會對數據源造成很大的瞬時壓力呢?

最明顯的思路是我們需要對數據源里面的數據進行分段檢索,當然我們檢索的數據肯定是有一個順序的,滿足流的ORDERED屬性,這樣也不至于重復取出數據,或者遺漏了數據。比如按照primary key的降序取出來。這樣分段檢索函數只需要(startId, limit)這樣一對參數就可以了,當然startId這個參數可以是泛型的,并不需要是整形。有了這個函數,我們就可以每次取出一段數據,外面包裝成一個Iterator來返回,而Iterator與Stream之間的互相轉換已經有了現成的接口:

StreamSupport.stream(spliteratorUnknownSize(iterator(), (NONNULL|IMMUTABLE|ORDERED)), false);

這樣就將遠端的一個數據源映射成了一個Stream.

對于Iterator的實現,G家的guava框架已經有了很完善的支持,在沒有Stream的日子里,Iterator可是被G家玩的出神入化,大家有興趣可以看看guava里面的框架庫。這里可以繼承com.google.common.collect.AbstractIterator來快速實現一個迭代器,只需要實現computeNext接口就可以了,超級方便。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容