今天整体来说很轻松,无压力度过,遇到公司的实习生在做一个需求,然后抓耳挠腮不会写,于是乎我就帮了他一把。
需求是这样的,我需要统计30天的数据从我的数据库记录里,然后以折线图的形式展现出来,共有七个分类
先把数据库的数据统计出来放入list里这个应该不难吧,不要说有些人不会写sql
算了贴出来吧
这样就统计出来这段时间的数据库里记录的数据了
那么问题就来了,
他问我,数据库中有些日期不存在,也就是统计出来的数据不连续啊,怎么办,他说看了网上好多方法是加个日历表,我说一天是java人就要用java 的方法实现,我说循环把他补上不就好了。他说还有值,我说map啊,他思索大半天,我知道现在的实习生动手能力差,好了,我也不为难你,我帮你写一个工具吧,就有了如下的代码
前面我们拿到了统计出来的list
/**
* 根据作业名称
*
* @param startDate开始时间
* @param endDate结束时间
* @param dataJobPath作业名称
* @return
*/
public Map<String, Object> queryCountByJobPath(String startDate,String endDate,String dataJobPath){
//老数据集合
Map<String, Object> result = Maps.newHashMap();
//参数集合
Map<String, Object> params = Maps.newHashMap();
//最终返回的数据集合
Map<String, Object> finallyResult = Maps.newHashMap();
int daySum = 0;//定义的时间差值
if(startDate!=null) {
params.put("startDate", startDate);
}
if(endDate!=null) {
params.put("endDate", endDate);
}
if(dataJobPath!=null) {
params.put("dataJobPath", dataJobPath);
}
/**
* 计算时间差值 当默认时间为空时时取今天的前30天为起始时间
*/
if(startDate==null || endDate ==null) {
daySum = 30;
endDate = sdf.format(new Date());
startDate = getStartDate(endDate);
}else {
daySum =(int) ((DateUtil.getDateFromStr(endDate).getTime()-DateUtil.getDateFromStr(startDate).getTime())/(24*60*60*1000));
}
/**
* 获取数据库中统计好的数据
*/
List<DataJobStatsVo> vos = dao.queryCountByJobPath(params);
/**
* 准备要塞入数据的集合
*/
List<Integer> read = Lists.newArrayList();
List<Integer> written = Lists.newArrayList();
List<Integer> input = Lists.newArrayList();
List<Integer> output = Lists.newArrayList();
List<Integer> updated = Lists.newArrayList();
List<Integer> rejected = Lists.newArrayList();
List<Integer> errors = Lists.newArrayList();
List<String> oldDates = Lists.newArrayList();//旧的时间集合
List<String> dateTime = Lists.newArrayList();//最终返回的时间集合
/**
* 将老数据塞入集合中
*/
for(DataJobStatsVo i:vos) {
Map<String, Object> value = Maps.newHashMap();
oldDates.add(sdf.format(i.getTime()).toString());
value.put("read", i.getRead());
value.put("written", i.getWritten());
value.put("input", i.getInput());
value.put("output", i.getOutput());
value.put("updated", i.getUpdated());
value.put("rejected", i.getRejected());
value.put("errors", i.getErrors());
result.put(sdf.format(i.getTime()).toString(),value);
}
//获取新的时间集合 即统计回来没有数据的日期补全
List<String> newDates = completionDate(oldDates, startDate, daySum);
/**
* 将没有数据的日期 存储值变成0 key时间 value值
*/
for(String j:newDates) {
boolean falg = false;
for(String key:result.keySet()) {
if(key.equals(j)) {
falg =true;
}
}
if(!falg) {
Map<String, Object> value = Maps.newHashMap();
value.put("read", 0);
value.put("written", 0);
value.put("input", 0);
value.put("output", 0);
value.put("updated", 0);
value.put("rejected", 0);
value.put("errors", 0);
result.put(j, value);
}
}
//上一步时间顺序已经被打乱了
//对获取到数据的集合进行按时间的排序
Map<String, Object> resultMap = sortMapByKey(result);
/**
* 把排序好的集合取出 放入事先准备好的list中
*/
for(String key:resultMap.keySet()) {
dateTime.add(key);
Map<String, Object> value= (Map<String, Object>) resultMap.get(key);
//当然底下的这些字符串一般我都会定义常量 让他们更加有理解意义,算了帮忙而已 ,自身写代码一定要严谨,毕竟码
//如其人,尽量少使用这些字符串去equals,定义常量才是规范性的代码
例如定义read read这里是读取Job作业里的数据结果就定义
interface JOBRESULT{
String READDATA = “READDATA”;
}去替换
看起来多好
///
for(String key1:value.keySet()) {
if("read".equals(key1)) {
read.add((Integer) value.get(key1));
}
if("written".equals(key1)) {
written.add((Integer) value.get(key1));
}
if("input".equals(key1)) {
input.add((Integer) value.get(key1));
}
if("output".equals(key1)) {
output.add((Integer) value.get(key1));
}
if("updated".equals(key1)) {
updated.add((Integer) value.get(key1));
}
if("rejected".equals(key1)) {
rejected.add((Integer) value.get(key1));
}
if("errors".equals(key1)) {
errors.add((Integer) value.get(key1));
}
}
}
//返回数据
finallyResult.put("date", dateTime);
finallyResult.put("read", read);
finallyResult.put("written", written);
finallyResult.put("input", input);
finallyResult.put("output", output);
finallyResult.put("updated", updated);
finallyResult.put("rejected", rejected);
finallyResult.put("errors", errors);
return finallyResult;
}
/**
* 补全日期的情况
*/
public List<String> completionDate(List<String> list ,String begin , int daySub){
List<String> dateResult = Lists.newArrayList();
//时间增加一天
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar yesterday = Calendar.getInstance();
yesterday.add(Calendar.DAY_OF_MONTH, 1);
String dateStr = sdf.format(yesterday.getTime());
//日期比较(求差多少天),时间也可以比较
Calendar now = Calendar.getInstance();
//字符串转化为时间
Calendar calendar10 = Calendar.getInstance();
Calendar calendar5 = Calendar.getInstance();
//循环处理日期数据,把缺失的日期补全。10是时间段内的天数,5是要处理的日期集合的天数
try {
Date date = sdf.parse(begin);
calendar10.setTime(date);
} catch (ParseException e) {
e.printStackTrace();
}
for(int curr = 0 ; curr <= daySub ; curr++){
boolean dbDataExist = false;
int index = 0;
for(int i = 0 ; i < list.size() ; i++){
try {
Date date2 = sdf.parse(list.get(i));
calendar5.setTime(date2);
} catch (ParseException e) {
e.printStackTrace();
}
if(calendar10.compareTo(calendar5) == 0){
dbDataExist = true;
index = i;
break;
}
}
if(dbDataExist){
dateResult.add(list.get(index));
}else{
dateResult.add(sdf.format(calendar10.getTime()));
}
//还原calendar10
calendar10.add(Calendar.DAY_OF_MONTH, 1 );
}
return dateResult;
}
/**
* 获取当前日期的前30天
*/
public String getStartDate(String endDate) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String startDate = "";
Calendar calc =Calendar.getInstance();
try {
calc.setTime(sdf.parse(endDate));
calc.add(calc.DATE, -30);
Date minDate = calc.getTime();
startDate = sdf.format(minDate);
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return startDate;
}
/**
* map按照key进行排序
* @param map
* @return
*/
public static Map<String, Object> sortMapByKey(Map<String, Object> map) {
if (map == null || map.isEmpty()) {
return null;
}
Map<String, Object> sortMap = new TreeMap<String, Object>(
new MapKeyComparator());//重写方法
sortMap.putAll(map);
return sortMap;
}
}
/**
* 比较器类
* @author 常青
*
*/
class MapKeyComparator implements Comparator<String>{
@Override
public int compare(String str1, String str2) {
return str1.compareTo(str2);
}
}
这样简单的补全日期并把数据按照顺序给了前端,前端只需要将这些list循环一贴折线图就出来了,给你们看一下这个效果,实习生也不容易的呢!!!!
就是这样一张图,好了今天的趣事说到这,每天分享明天见呢!!!!!