java+mybatis 數據統計每天/月 並補全日期


service

public List<DemoVO> queryNum(DemoDTO dto) {
		List<DemoVO> list = baseMapper.queryNum(dto);

		/**
		 * 補全時間
		 * 查詢范圍:1-昨天,2-近?天,3-本月,4-本年
		 */
		List<DemoVO> result = new ArrayList<>();
		int queryRange = dto.getQueryRange();
		if (queryRange == 0 || queryRange == 1){
			if (list.size() != 1) {
				result.add(DemoVO.getTemp(LocalDate.now().minusDays(1).toString()));
			}
		} else if (queryRange == 2) {
			if (list.size() != dto.getQueryDay()) {
				LocalDate now = LocalDate.now();
				String startDate = now.minusDays(Long.parseLong(dto.getQueryDay() - 1 + "")).toString();
				String endDate = now.toString();
				result = this.completeData(1, startDate, endDate, list);
			}
		} else if (queryRange == 3) {
			LocalDate now = LocalDate.now();
			// 獲取當前天數
			int day = now.getDayOfMonth();
			if (list.size() != day) {
				String startDate = now.minusDays(Long.parseLong(day - 1 + "")).toString();
				String endDate = now.toString();
				result = this.completeData(1, startDate, endDate, list);
			}
		} else {
			YearMonth now = YearMonth.now();
			// 獲取當前月數
			int month = now.getMonthValue();
			if (list.size() != month) {
				String startDate = now.minusMonths(Long.parseLong(month - 1 + "")).toString();
				String endDate = now.toString();
				result = this.completeData(2, startDate, endDate, list);
			}

		}

		return result;
	}

	/**
	 * 補全數據
	 * @param dateType	日期類型:1-日,2-月
	 * @param startDate	開始日期
	 * @param endDate	結束日期
	 * @param target	未補全的列表
	 * @return 補全后的列表
	 */
	private List<DemoVO> completeData(int dateType, String startDate, String endDate, List<DemoVO> target) {

		List<DemoVO> result = new ArrayList<>();

		// 轉換數據庫查詢到的數據
		Map<String, DemoVO> map = target.stream()
			.collect(Collectors.toMap(DemoVO::getResultDate, Function.identity()));

		if (dateType == 1) {
			// 間隔的日期列表
			List<LocalDate> dates = RangeDateUtil.getRangeDays(startDate, endDate);
			// 遍歷
			dates.forEach(dateTemp -> {
				if (map.containsKey(dateTemp.toString())) {
					result.add(map.get(dateTemp.toString()));
				} else {
					// 沒有這一天的數據,默認補0
					result.add(DemoVO.getTemp(dateTemp.toString()));
				}
			});
		} else {
			// 間隔的月份列表
			List<YearMonth> dates = RangeDateUtil.getRangeYears(startDate, endDate);
			// 遍歷
			dates.forEach(dateTemp -> {
				if (map.containsKey(dateTemp.toString())) {
					result.add(map.get(dateTemp.toString()));
				} else {
					// 沒有這一天的數據,默認補0
					result.add(DemoVO.getTemp(dateTemp.toString()));
				}
			});
		}
		return result;
	}

mapper.xml

	<!--數據統計-->
    <select id="queryNum" resultType="com.soldier.vo.DemoVO">
        select
        <!-- 日期,按年時截取到月份 -->
        <choose>
            <when test="queryRange == 4">
                DATE_FORMAT(create_time, '%Y-%m') resultDate,
            </when>
            <otherwise>
                DATE_FORMAT(create_time, '%Y-%m-%d') resultDate,
            </otherwise>
        </choose>
        <!-- 總數 -->
        count(id) as resultNum,
        from (
            select * from t_demo
            where is_deleted = 0
            <!-- 查詢范圍:1-昨天,2-近?天,3-本月,4-本年 -->
            <choose>
                <when test="queryRange == 1">
                    and TO_DAYS(NOW())-TO_DAYS(create_time) = 1
                </when>
                <when test="queryRange == 2">
                    and DATE_SUB(CURDATE(), INTERVAL #{queryDay} DAY) &lt;= date(update_time)
                </when>
                <when test="queryRange == 3">
                    and DATE_FORMAT(update_time, '%Y%m') = DATE_FORMAT(CURDATE() , '%Y%m')
                </when>
                <otherwise>
                    and DATE_FORMAT(update_time, '%Y') = DATE_FORMAT(CURDATE() , '%Y')
                </otherwise>
            </choose>
        ) table_temp
        group by resultDate;
    </select>

DTO和VO對象

@Data
public class DemoDTO implements Serializable {

	private static final long serialVersionUID = 1L;

	/**
	 * 查詢范圍:1-昨天,2-近?天,3-本月,4-本年
	 */
	private Integer queryRange;

	/**
	 * 查詢天數:查詢范圍為2時指定的天數
	 */
	private Integer queryDay;

}

@Data
public class DemoVO implements Serializable {

	private static final long serialVersionUID = 1L;

	/**
	 * 日期
	 */
	private String resultDate;

	/**
	 * 總數
	 */
	private int resultNum;
	
	/**
	 * 空模板
	 */
	public static DemoVO getTemp(String resultDate) {
		OrderDataStatisticsVO temp = new OrderDataStatisticsVO();
		temp.setResultDate(resultDate);
		return temp;
	}
}

獲取間隔的日期列表工具類

public class RangeDateUtil {

////////////////////////////////////////////  YearMonth ////////////////////////////////////////////
	/**
	 * 獲取間隔的月份列表
	 * @param preYear 開始月份
	 * @param endYear 截止月份
	 */
	public static List<YearMonth> getRangeYears(YearMonth preYear, YearMonth endYear) {
		List<YearMonth> years = new ArrayList<>();
		// 間隔的月數
		long betweenYears = ChronoUnit.MONTHS.between(preYear, endYear);
		if (betweenYears < 1) {
			// 開始日期<=截止日期
			return years;
		}
		// 創建一個從開始日期、每次加一個月的無限流,限制到截止月份為止
		Stream.iterate(preYear, c -> c.plusMonths(1))
			.limit(betweenYears + 1)
			.forEach(years::add);
		return years;
	}

	/**
	 * 獲取指定月份前的指定月數的日期列表
	 * @param endYear		截止月份
	 * @param betweenYears	間隔月數
	 */
	public static List<YearMonth> getPreRangeYears(YearMonth endYear, int betweenYears) {
		YearMonth preYear = endYear.minusYears(betweenYears);
		return getRangeYears(preYear, endYear);
	}

	/**
	 * 獲取指定月份前的指定月數的日期列表
	 * @param preYear		開始月份
	 * @param betweenYears	間隔月數
	 */
	public static List<YearMonth> getEndRangeYears(YearMonth preYear, int betweenYears) {
		YearMonth endYear = preYear.plusMonths(betweenYears);
		return getRangeYears(preYear, endYear);
	}

////////////////////////////////////////////  LocalDate ////////////////////////////////////////////
	/**
	 * 獲取間隔的日期列表
	 * @param preDate 開始日期
	 * @param endDate 截止日期
	 */
	public static List<LocalDate> getRangeDays(LocalDate preDate, LocalDate endDate) {
		List<LocalDate> dates = new ArrayList<>();
		// 間隔的天數
		long betweenDays = ChronoUnit.DAYS.between(preDate, endDate);
		if (betweenDays < 1) {
			// 開始日期<=截止日期
			return dates;
		}
		// 創建一個從開始日期、每次加一天的無限流,限制到截止日期為止
		Stream.iterate(preDate, c -> c.plusDays(1))
			.limit(betweenDays + 1)
			.forEach(dates::add);
		return dates;
	}

	/**
	 * 獲取指定日期前的指定天數的日期列表
	 * @param endDate		截止日期
	 * @param betweenDays	間隔天數
	 */
	public static List<LocalDate> getPreRangeDays(LocalDate endDate, int betweenDays) {
		LocalDate preDate = endDate.minusDays(betweenDays);
		return getRangeDays(preDate, endDate);
	}

	/**
	 * 獲取指定日期后的指定天數的日期列表
	 * @param preDate		開始日期
	 * @param betweenDays	間隔天數
	 */
	public static List<LocalDate> getEndRangeDays(LocalDate preDate, int betweenDays) {
		LocalDate endDate = preDate.plusDays(betweenDays);
		return getRangeDays(preDate, endDate);
	}

////////////////////////////////////////////  Date ////////////////////////////////////////////
	/**
	 * 獲取間隔的日期列表
	 * @param preDate 開始日期
	 * @param endDate 截止日期
	 */
	public static List<Date> getRangeDays(Date preDate, Date endDate) {
		List<Date> dates = new ArrayList<>();
		// 間隔的天數
		int betweenDays = (int) ((endDate.getTime() - preDate.getTime()) / (1000*3600*24));
		if (betweenDays < 1) {
			// 開始日期<=截止日期
			return dates;
		}
		// 創建一個從開始日期、每次加一天的無限流,限制到截止日期為止
		Stream.iterate(preDate, c -> DateUtil.plusDays(c, 1))
			.limit(betweenDays + 1)
			.forEach(dates::add);
		return dates;
	}

	/**
	 * 獲取指定日期前的指定天數的日期列表
	 * @param endDate		截止日期
	 * @param betweenDays	間隔天數
	 */
	public static List<Date> getPreRangeDays(Date endDate, int betweenDays) {
		Date preDate = DateUtil.minusDays(endDate, betweenDays);
		return getRangeDays(preDate, endDate);
	}

	/**
	 * 獲取指定日期后的指定天數的日期列表
	 * @param preDate		開始日期
	 * @param betweenDays	間隔天數
	 */
	public static List<Date> getEndRangeDays(Date preDate, int betweenDays) {
		Date endDate = DateUtil.plusDays(preDate, betweenDays);
		return getRangeDays(preDate, endDate);
	}

////////////////////////////////////////////  String ////////////////////////////////////////////
	/**
	 * 獲取間隔的月份列表
	 * @param preYear 開始月份(yyyy-MM格式)
	 * @param endYear 截止月份(yyyy-MM格式)
	 */
	public static List<YearMonth> getRangeYears(String preYear, String endYear) {
		YearMonth pDate = YearMonth.parse(preYear);
		YearMonth eDate = YearMonth.parse(endYear);
		return getRangeYears(pDate, eDate);
	}
	/**
	 * 獲取間隔的日期列表
	 * @param preDate 開始日期(yyyy-MM-dd格式)
	 * @param endDate 截止日期(yyyy-MM-dd格式)
	 */
	public static List<LocalDate> getRangeDays(String preDate, String endDate) {
		LocalDate pDate = LocalDate.parse(preDate);
		LocalDate eDate = LocalDate.parse(endDate);
		return getRangeDays(pDate, eDate);
	}
}


免責聲明!

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



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