在进行数据库数据统计时,比如按天统计数据,一个月中有一些天没有数据的,数据库也就没查出来,对于后台来说这没什么。但是前端展示的时候要补全缺失的日期数据,比如2020-05-12没有数据,就添加键日期,并把值补为0。(假如后台查询的数据数据结构为List<Map<String, Object>>)。
如图,数据库查询出来的统计数据如下
我的需求是查询出近30天的所有数据,很显然,上面的数据是有缺失的,我需要把“2020-04-13”到“2020-05-12”(当前)的所有数据都列出来,没有的话就补0。
方式一:依赖数据库解决,新建一个数据表,left join 来查询,或者拼接 union。此处先不做讲解。
方式二:在程序中进行补全。
- 写一个补全日期工具类,给定指定的开始和结束日期,返回两者之间所有的日期的字符串列表
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
/**
* 补全日期工具类.
*
* @author linzp
* @version 1.0.0
* CreateDate 2020/5/11 17:13
* description
*/
public final class CompletionDateUtils {
/**
* 隐藏构造方法.
*/
private CompletionDateUtils() {
}
/**
* 数据库查询出来的统计数据有时候日期是不连续的.
* 但是前端展示要补全缺失的日期.
* 此方法返回一个给定日期期间的所有日期字符串列表.
* 具体在业务逻辑中去判断补全.
*
* @param startDate 开始日期
* @param endDate 结束日期
* @return
*/
public static List<String> completionDate(
LocalDateTime startDate,
LocalDateTime endDate) {
//日期格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
List<String> dateList = new ArrayList<>();
//遍历给定的日期期间的每一天
for (int i = 0; !Duration.between(startDate.plusDays(i), endDate).isNegative(); i++) {
//添加日期
dateList.add(startDate.plusDays(i).format(formatter));
}
return dateList;
}
/**
* main.
*
* @param args
*/
public static void main(String[] args) {
//测试过去30天
completionDate(LocalDateTime.now().minusDays(29), LocalDateTime.now());
}
}
2. 得到指定日期之间的列表如下图
3. 得到指定日期之间的列表后,遍历列表,然后和数据库查询出来的数据进行比较,如果相同则添加数据库查询的Map到新的列表,不同则构造一个新的Map(key:日期,value:0),然后添加到新的列表。核心代码如下:
//获取日期
LocalDateTime startDate = LocalDateTime.now().minusDays(29);
LocalDateTime endDate = LocalDateTime.now();
//3.补全为空的日期
//补全后的结果
List<Map<String, Object>> result = new ArrayList<>();
boolean dbDateExist = false;
List<String> dateList = CompletionDateUtils.completionDate(startDate, endDate);
log.info("指定日期期间所有日期字符串为=={}",dateList);
for (String date : dateList) {
//table为数据库查询出来的对象列表,结构为List<Map<String, Object>>
for (Map<String, Object> row : table) {
if (row.get("daytime").equals(date)) {
//集合已包含该日期
dbDateExist = true;
result.add(row);
break;
}
}
//添加补全的数据到最后结果列表
if (!dbDateExist) {
Map<String, Object> temp = new HashMap<>(2);
temp.put("daytime", date);
temp.put("total", 0);
result.add(temp);
}
//状态修改为不存在
dbDateExist = false;
}
4.其中result为补全的最终结果,打印拼接的最终结果如下:
到此补全日期成功啦。工具类做成了指定日期之间。可以任意设置指定的日期。个人觉得这种方式比使用SQL来解决的方式要好一点。
码字不易,觉得有帮助到的亲们点个赞吧 ~