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) <= 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);
}
}