1. 程式人生 > 實用技巧 >程式碼改造實錄--使用Stream替代多次資料庫查詢

程式碼改造實錄--使用Stream替代多次資料庫查詢

  近來接手了一套程式碼,裡面有很多感覺可以改進的地方,修改後做個記錄。

  話不多說,直接上程式碼。程式碼的大意是對一系列物件資料按照某欄位來統計另一個欄位的和。原來的程式碼,呼叫了五次資料介面:

int tsjt = measureRepository.findScoreByTypeAndUserIdAndDate("tenderness", userId, date);
int tnsj = measureRepository.findScoreByTypeAndUserIdAndDate("swelling", userId, date);
int stij = measureRepository.findScoreByTypeAndUserIdAndDate("temperature", userId, date);

int leftHand = measureRepository.findScoreByCodeAndUserIdAndDate("left_grip", userId, date);
int rightHand = measureRepository.findScoreByCodeAndUserIdAndDate("right_grip", userId, date);

  對應兩個資料介面:

@Query(
    value = "select ifnull(sum(score),0) as score from pride_measured where type=:type and user_id=:userId and date=:date ",
    nativeQuery 
= true) int findScoreByTypeAndUserIdAndDate(String type, Integer userId, Date date); @Query( value = "select ifnull(sum(score),0) as score from pride_measured where code=:code and user_id=:userId and date=:date", nativeQuery = true) int findScoreByCodeAndUserIdAndDate(String code, Integer userId, Date date);Date date);

  改造為只調用一次資料查詢介面,然後通過java8 Stream特性來處理:

        Measure measureQuery = new Measure();
        measureQuery.setUserId(userId);
        measureQuery.setDate(date);
        List<Measure> list = measureService.queryMeasures(measureQuery);

        Map<String, IntSummaryStatistics> measuresByType = list.stream()
            .collect(Collectors.groupingBy(Measure::getType, Collectors.summarizingInt(Measure::getScore)));
        int tsjt = measuresByType.get("tenderness") == null ? 0 : (int)measuresByType.get("tenderness").getSum();
        int tnsj = measuresByType.get("swelling") == null ? 0 : (int)measuresByType.get("swelling").getSum();
        int stij = measuresByType.get("temperature") == null ? 0 : (int)measuresByType.get("temperature").getSum();

        Map<String, Integer> measuresByCode = list.stream().filter(item -> ("grip".equals(item.getType())))
            .collect(Collectors.toMap(Measure::getCode, Measure::getScore));
        int leftHand = measuresByCode.get("left_grip") == null ? 0 : measuresByCode.get("left_grip");
        int rightHand = measuresByCode.get("right_grip") == null ? 0 : measuresByCode.get("right_grip");

  分別三次測試該方法的原來程式碼執行時間和現程式碼執行時間(其中包含無符合條件資料和有符合條件資料兩種情況),原來執行時間分別為:1059ms、1281ms、1371ms,改造後執行時間分別為:928ms、922ms、1067ms,可以看到執行時間在同樣情況下改造後有明顯的改觀。

  本次改造,除了減少了訪問資料庫次數節省時間外,還把處理集中到了服務程式中,便於分散式擴充套件。