项目中需要一段时间周期内,按天统计数据,之前我实现了一个版本,思路如下:
根据输入到查询时间段,拆分成每天到时间间隔,然后每个间隔从数据库查询。
比如查询1月1号8:00到1月10号9:00,查询间隔分别为1月1号8点-1月2号0点,1月2号0点到1月2号23:59:59,依次类推。
后来发现这个思路有些笨,而且频繁查询数据库,性能较低。利用map,一次性查出时间条件内到所有数据,用日期作为key放入map,如果key已经存在,则拿出值相加,如果key不存在,直接放入。当然,key会忽略时间,只是日期。
private Map<String, Long> getUvCount(String channelFlag, Date startTime, Date endTime) {
Map<String, Long> uvMap = new HashMap<>();
String startTimeString = DateUtils.formateDate(startTime, DateUtils.FORMAT_DATE);
String endTimeString = DateUtils.formateDate(endTime, DateUtils.FORMAT_DATE);
List<ChannelUpStreamInterfaceLog> channelUpStreamInterfaceLogList = channelUpStreamInterfaceLogMapper
.selectData(DateUtils.FORMAT_DATE, channelFlag, startTimeString, endTimeString);
if (channelUpStreamInterfaceLogList != null && !channelUpStreamInterfaceLogList.isEmpty()) {
channelUpStreamInterfaceLogList.forEach(channelUpStreamInterfaceLog -> {
String date = DateUtils.dateToStr(channelUpStreamInterfaceLog.getCreateTime(), 11);
if (uvMap.containsKey(date)) {
uvMap.put(date, uvMap.get(date) + (channelUpStreamInterfaceLog.getuV()));
} else {
uvMap.put(date, channelUpStreamInterfaceLog.getuV());
}
});
}
return uvMap;
}
原来的代码如下:
uvCount = 0L;
String startTimeString=DateUtils.formateDate(startTime,DateUtils.FORMAT_DATE);
String endTimeString=DateUtils.formateDate(endTime,DateUtils.FORMAT_DATE);
List<ChannelUpStreamInterfaceLog> channelUpStreamInterfaceLogList=channelUpStreamInterfaceLogMapper.selectData(DateUtils.FORMAT_DATE,channelFlag,startTimeString,endTimeString);
if (channelUpStreamInterfaceLogList!=null&&!channelUpStreamInterfaceLogList.isEmpty())
{
channelUpStreamInterfaceLogList.forEach(channelUpStreamInterfaceLog -> {
uvCount += channelUpStreamInterfaceLog.getuV();
});
}
return uvCount;
}
starttime和endtime为每天分割的单元。
综上,充分利用hashmap的特性,不仅仅是存储key value,