關於多數據源(除自己數據庫外,另一部分數據需通過接口調取第三方獲取)的查詢問題


同樣,還是一次工作上遇到的問題的記錄,當時也是搞了挺久才搞出來的,雖然不太完美,但是誤差方面在我的項目里還算可以接受,哪位老哥有更好的辦法還請指導下,哪怕評論里留個網頁鏈接我去看也好,多謝了。

具體問題描述大致如下:

  客戶需要app能查詢出所有訂單,分頁並且按時間倒序排列,現在所有的消費訂單數據在我們自己的數據庫里,而所有的充值訂單數據其實在第三方那里(其實我們自己也記錄了一筆,但是數據結果不可靠,因此還是要取用對方的),關於從第三方獲取數據的參數概括是(用戶唯一標識,每頁顯示行數,當前頁數),即(userId,pageSize,pageNo),其中pageSize要求小於50。

經過思考,需要解決的問題主要在於:

  1.如何從第三方獲取我需要的數據

  2.整合我們庫里的數據,第三方獲取的數據,進行時間倒序排列,並返回給app

實際上第二點很好解決,只要寫一個排序類,對整合后的數據進行排序即可,最主要難點在於第一點,如何確定調取第三方接口的入參pageSize和pageNo,然后還要把之前已經展示過的數據排除掉。

具體解決方法如下:

  1.首先,我用了cache,用於記錄app已展示的(消費記錄數)(充值記錄數),即(我方庫數據展示量)(第三方數據展示量),暫定參數為ownother,當app端傳的頁數為第一頁時,將這兩個數據都置為0.

  2.查詢接下來需要展示的數據中,我方的數據,這點沒什么好說的,正常的查自己數據庫即可,需要查出來的量為own<rownum<own+appPageSize,其中appPageSize是指app的入參,app端的頁顯示行數

  3.然后查詢需要展示的數據中,第三方的數據,關於確定調取第三方接口入參的方法如下:

 1 /**
 2      * 獲取第三方訂單查詢接口所需要的參數
 3      * @param start        起始數據量
 4      * @param end        結束數據量
 5      * @param size        展示數據量
 6      * @return
 7      * Map,包含兩個參數,pagenum頁數,pagesize頁顯示行數
 8      */
 9     public static Map<String,Integer> getWdPara(int start,int end,int size){
10         Map<String,Integer> map=new HashMap<>();
11         if (start<size||start/size<1) {
12             map.put("pagenum", 1);
13             map.put("pagesize", 10*((end/10)+1));
14         }else{
15             if (start/size==end/size) {
16                 map.put("pagenum", (end/size)+1);
17                 map.put("pagesize", size);
18             }else {
19                 map=getWdPara(start, end, size+1);
20             }
21         }
22         return map;
23     }

其中三個參數的關系是end=start+size,實際上start入參的值就是other,而size入參的值就是appPageSize。而出參的兩個參數就分別是調取第三方時候的入參pageSize和pageNo了。關於如何確定這個方法可以獲取想要的參數,說起來有點繞,我數學也不太好,當時打了挺久的草稿,參照如下,如果看不懂直接跳過就好。。。因為我自己也經常忘記什么意思:

默認app端展示數據量為10條,所以從第三方中獲取的數據需要包含other+10條,因為根據時間倒序,這中間存在沒有數據是消費數據,全是充值數據的情況,即所有展示數據均來自於第三方。

第三方數據的起始-截止數據量      pageSize參數,即s    pageNo參數,即n  實際取到的數據量

8-18                    20            1        1-20

18-28                    15             2        15-30

28-38                    20             2        20-40

。。。

一開始是這樣草稿打下去的,后來找規律后發現,其實就和查自己數據庫一樣,保證查到的數據包含起始數據和終止數據即可,即       

( 頁數-1)*頁顯示行數>起始數據,頁數*頁顯示行數>終止數據

然后進行幾次舉例驗證后,就得出上述獲取參數的方法了。

至此,最難的一步已經完成了,即已經獲取到所有需要的數據了。

  4.然后進行下一步,需要去除掉之前已經展示過了的數據,就如上面例子,我們獲取到的數據量,其實是大於需要的數據量,有一部分數據可能之前已經展示了,因此在這里需要將之前展示了的數據去除掉,代碼如下 

 1   /**
 2      * 處理訂單數據,排除之前顯示過的數據
 3      * @param dataList     待處理的list
 4      * @param start        數據起始
 5      * @param size         頁顯示行數
 6      */
 7     public static void dealList(List<Map<String, String>> dataList,int start,int size){
 8         int removeNum=start%size;
 9         for (int i = 0; i < removeNum; i++) {
10             dataList.remove(0);
11         }
12     }

即起始數據除以頁顯示行數,取余數,然后獲取到的數據量從前往后刪除這個余數量的數據即可,這個余數量即之前已經展示用過的數據量。和上面獲取參數一樣,這個計算方法,也是我自己寫了好幾個例子,然后找規律寫出來的。。。數學不好,見諒,我也不知道邏輯上該怎么解釋,反正根據例子找規律,發現這樣寫沒問題。

  5.再然后就沒啥問題了,要展示的充值數據,消費數據都已經全部獲取到了,只要將一些參數名稱處理下,確保保持一致,放在一個list里面,然后寫個排序方法,根據訂單時間進行倒序,排完序以后,獲取前appPageSize個數據返回給前端即可,排序代碼如下:

 1   /**
 2      * 數據進行排序,按照時間倒序排序
 3      * @param list
 4      */
 5     @SuppressWarnings("unchecked")
 6     public static void sortTimeMethod(List<Map<String,String>> list){
 7         Comparator comp= new Comparator<Map<String, String>>(){
 8             //返回值大於0時,兩者交換順序
 9             @Override
10             public int compare(Map<String, String> p1,Map<String, String> p2){
11                 String p1Date=Tools.processNull(p1.get("order_date"));
12                 String p2Date=Tools.processNull(p2.get("order_date"));
13                 if ("".equals(p1Date)
14                         ||"".equals(p2Date)) {
15                     return 0;
16                 }else {
17                     //如果o1時間早於等於o2時間,則o1排在后面
18                     if (!DateUtil.formatDate(p1Date).after(DateUtil.formatDate(p2Date))) {
19                         return 1;
20                     }else {
21                         return -1;
22                     }
23                 }
24             }
25         };
26         Collections.sort(list, comp);
27     }

  6.當然,這時候也別忘記更新cache里面的數據,根據最終返回給前端的數據,判斷有多少消費數據和充值數據,對ownother進行相應的累加。

以上就全部完成。不過就和我之前說的,有誤差,很有局限性,跟我們使用場景有關,因此不是很具備參考性,相關說明如下:

  1.我們是APP展示用的,場景中無法跳頁,也就是用戶只能選擇先看第一頁,再看第二頁數據,這樣依次下排,如果存在跳頁,我這個方法應該不行。

  2.當用戶在看訂單的同時,無法進行充值或消費操作,進行充值或消費等產生訂單的操作后,重新來查詢必定是從第一頁開始,因此那種查了一會兒,突然增加一條訂單了,這種情況是不會出現的,否則我這方法會存在問題,即cache里的值不准了,導致的結果就是查詢的數據也不准了,有個訂單會展示兩次。

 


可能看上去條理不是很清晰,有點混亂。。。但是盡力了,其實一開始沒打算寫,后來隔了半個多月,突然發現自己這個代碼看不懂了,然后重新理解了半天,想想這個當初也是自己搞了挺久才弄出來的,怕以后又忘記了,於是此時開始寫這篇隨筆,本身就是隔了半個月后再寫,思路就不是很清晰,結果寫了一小半,客戶又來事情了,於是忙去了。。。然后一段時間沒閑下來,再然后忙着忙着就給忘了。。。。直到今天,已經是半年后了,再次來續寫的時候,腦子就更亂了,強行看着半篇內容加自己原先的代碼,將其續寫完成。主要用處估計也就是以后自己如果遇到相同問題,給自己一個提點,一個思路,防止到時候自己腦子又轉不過來。

            


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM