现有两张表A表和B表,A表存放的是各省市的认证次数,B表存放的是各省市的申领次数,重点关注dq,cs这两个字段,其他的字段可忽略
A表(省市认证次数表)
B表(省市申领次数表)
项目中有以下需求:
现要求统计各省市的认证次数和申领次数,以及认证和申领次数之和,以此再地图上展示数据。
A表和B表中都有dq和cs这两个字段,dq都表示行政区划编码,A表中的cs表示认证次数,B表中的cs表示申领次数,将两张表中dq值相同的分组放进同一个map中,再计算认证次数和申领次数之和,这个需求很明显就是Map要合并key的场景,将查出的数据进行合并,再分组,可使用Lambda表达式实现,部分代码如下:
Controller代码:
/**
* 4、区域省份认证情况统计
* @return
*/
@PostMapping(value="/loadProvinceAuthData")
public ResponseVO loadProvinceAuthData() {
try {
Map<String, Object> data = new HashMap<>();
ReportExternalRiskEntity request = new ReportExternalRiskEntity();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date=new Date();
String startTime = sdf.format(date)+" 00:00:00";
String endTime = sdf.format(date)+" 23:59:59";
request.setStartTime(startTime);
request.setEndTime(endTime);
//List<Map<String,Object>> provinceAuthDataList = reportIdentityAuthStatService.getProvinceAuthDataList(request);
List<Map<String,Object>> provinceAuthDataList = shenLingRenZhengService.getProvinceAuthDataList(request);
data.put("list",provinceAuthDataList);
return RespUtil.success(data);
} catch (Exception e) {
log.error("请求接口loadProvinceAuthData报错->{}",e);
return RespUtil.sysError(String.valueOf(ResultCodeEnum.SYSTEM_ERROR));
}
}
重点看Service代码中如何处理:
@Override
public List<Map<String, Object>> getProvinceAuthDataList(ReportExternalRiskEntity request) throws Exception {
List<Map<String, Object>> xzqhDataMapList = new ArrayList<>();
Map queryParams = new HashMap();
Date date=new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String queryDate = sdf.format(date);
queryParams.put("ywrq",queryDate);
List<Map<String, Object>> rzcsDqDataList = reportDpRzcsDqMapper.queryRzcsDqByYwrq(queryParams);//数据库查询认证次数返回的list
List<Map<String, Object>> slcsDqDataList = reportDpSlcsDqMapper.querySlcsDqByYwrq(queryParams);//数据库查询申领次数返回的list
PageData xzqhMap = CacheUtils.getTyZdMap(StaticVar.PROVICE_XZQH);
if(CollectionUtils.isNotEmpty(rzcsDqDataList) && CollectionUtils.isEmpty(slcsDqDataList)){ //认证区域统计查询List有数据
for (Map<String, Object> rzcsMap : rzcsDqDataList) {
Map<String, Object> xzqhDataMap = new HashMap<>();
//String authnumStr = (String) rzcsMap.get("authnum"); //注意:会报错java.math.BigDecimal cannot be cast to java.lang.Integer,先转成String类型,再转Integer
//Integer authNum = (Integer) rzcsMap.get("authnum")==null?0:(Integer) rzcsMap.get("authnum");
String authnumStr = StringUtils.isBlank(String.valueOf(rzcsMap.get("authnum")))?"0":String.valueOf(rzcsMap.get("authnum"));
Integer authNum = Integer.parseInt(authnumStr);
String rzdq = (String) rzcsMap.get("dq");
String rzdq_bm = rzdq+StaticVar.XZQH_SUFFIX;
xzqhDataMap.put("bm",rzdq_bm);
xzqhDataMap.put("name",xzqhMap.get(rzdq_bm));
xzqhDataMap.put("authNum",authNum);
xzqhDataMap.put("applyNum",0);
xzqhDataMap.put("totalNum",authNum);
xzqhDataMap.put("leval",getLeval(authNum));
xzqhDataMapList.add(xzqhDataMap);
}
}else if(CollectionUtils.isNotEmpty(slcsDqDataList) && CollectionUtils.isEmpty(rzcsDqDataList)){//申领区域统计查询List有数据
for (Map<String, Object> slcsMap : slcsDqDataList) {
Map<String, Object> xzqhDataMap = new HashMap<>();
//Integer applyNum = (Integer) xzqhDataMap.get("applynum");
String applynumStr = StringUtils.isBlank(String.valueOf(slcsMap.get("applynum")))?"0":String.valueOf(slcsMap.get("applynum"));
Integer applyNum = Integer.parseInt(applynumStr);
String sldq = (String) xzqhDataMap.get("dq");
String sldq_bm = sldq+StaticVar.XZQH_SUFFIX;
xzqhDataMap.put("bm",sldq_bm);
xzqhDataMap.put("name",xzqhMap.get(sldq_bm));
xzqhDataMap.put("authNum",0);
xzqhDataMap.put("applyNum",applyNum);
xzqhDataMap.put("totalNum",applyNum);
xzqhDataMap.put("leval",getLeval(applyNum));
xzqhDataMapList.add(xzqhDataMap);
}
}else if(CollectionUtils.isNotEmpty(rzcsDqDataList) && CollectionUtils.isNotEmpty(slcsDqDataList)) { //申领和认证都有数据
for (Map<String, Object> rzcsMap : rzcsDqDataList) {
String authnumStr = StringUtils.isBlank(String.valueOf(rzcsMap.get("authnum")))?"0":String.valueOf(rzcsMap.get("authnum"));
Integer authNum = Integer.parseInt(authnumStr);
rzcsMap.put("authNum",authNum);//将authnum替换为authNum
rzcsMap.remove("authnum");//去掉那个authNum
}
for (Map<String, Object> slcsMap : slcsDqDataList) {
String applynumStr = StringUtils.isBlank(String.valueOf(slcsMap.get("applynum")))?"0":String.valueOf(slcsMap.get("applynum"));
Integer applyNum = Integer.parseInt(applynumStr);
slcsMap.put("applyNum",applyNum);
slcsMap.remove("applynum");
}
//合并,两个数据list放入一个新的list中
List<Map<String, Object>> new_dataList = new ArrayList<>();
new_dataList.addAll(rzcsDqDataList);
new_dataList.addAll(slcsDqDataList);
//先分组,将key值相同的放在一个map中
xzqhDataMapList = new_dataList.stream()
.collect(Collectors.groupingBy(group -> group.get("dq").toString())) // 根据map中id的value值进行分组, 这一步的返回结果Map<String,List<Map<String, Object>>>
.entrySet() // 得到Set<Map.Entry<String, List<Map<String, Object>>>
.stream()
.map(m -> { // 进入映射环境
// m.getValue()的结果是 List<Map<String, Object>>
Map<String, Object> collect = m.getValue().stream()
// o.entrySet() 的结果是 Set<Map.Entry<String, Object>>
.flatMap(o -> o.entrySet().stream()).filter(e -> e.getValue() != null)//过滤下,value需要是不为空的,否则报错
// (m1, m2) -> m1 的意思是如果key相同 m1 == m2 则value使用m1(此处为rzcsDqDataList中的值)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (m1, m2) -> m1
));
return collect;
}).sorted(Comparator.comparing(m -> m.get("dq").toString())).collect(Collectors.toList());
System.out.println("处理后的xzqhDataMapList为:"+xzqhDataMapList);
System.out.println("处理后的xzqhDataMapList的Json为:"+ JSON.toJSONString(xzqhDataMapList));
//处理分组后的数据,得到认证次数和申领次数之和totalNum
for (Map<String, Object> xzqhDataMap : xzqhDataMapList) {
String dq = (String) xzqhDataMap.get("dq");
int totalNum = 0;
Integer authNum = 0;
Integer applyNum = 0 ;
if(xzqhDataMap.containsKey("authNum")){
String authnumStr = StringUtils.isBlank(String.valueOf(xzqhDataMap.get("authNum")))?"0":String.valueOf(xzqhDataMap.get("authNum"));
authNum = Integer.parseInt(authnumStr);
}
if(xzqhDataMap.containsKey("applyNum")){
String applynumStr = StringUtils.isBlank(String.valueOf(xzqhDataMap.get("applyNum")))?"0":String.valueOf(xzqhDataMap.get("applyNum"));
applyNum = Integer.parseInt(applynumStr);
}
totalNum = authNum + applyNum;
int level = getLeval(totalNum);
xzqhDataMap.put("totalNum",totalNum);
xzqhDataMap.put("level",level);
if(!xzqhDataMap.containsKey("authNum")){ //若Map中没有"authNum",补key,"authNum"
xzqhDataMap.put("authNum",0);
}
if(!xzqhDataMap.containsKey("applyNum")){ 若Map中没有"applyNum",补key,"applyNum"
xzqhDataMap.put("applyNum",0);
}
//行政区划翻译
String xzqh_bm = dq+StaticVar.XZQH_SUFFIX;
xzqhDataMap.put("bm",xzqh_bm);
xzqhDataMap.put("name",xzqhMap.get(xzqh_bm));
xzqhDataMap.remove("dq");
}
}
return xzqhDataMapList;
}
//计算等级level值
private static int getLeval(int totalNum) {
int leval = 0;
if(totalNum==0){
return leval;
}
if(totalNum >=1 && totalNum <=900){
leval = 1;
}else if(totalNum >=901 && totalNum <=2000){
leval = 2;
}else if(totalNum >=2001 && totalNum <=4000){
leval = 3;
}else if(totalNum >=4001){
leval = 4;
}
return leval;
}
<!--查询认证次数返回的list-->
<select id="queryRzcsDqByYwrq" parameterType="java.util.Map" resultType="java.util.Map">
select dq,sum(cs) as authNum from
report_dp_rzcs_dq
where ywrq =#{ywrq}
group by dq
</select>
<!--查询申领次数返回的list-->
<select id="querySlcsDqByYwrq" parameterType="java.util.Map" resultType="java.util.Map">
select dq,sum(cs) as applyNum from
report_dp_slcs_dq
where ywrq = #{ywrq}
group by dq
</select>
请求接口http://127.0.0.1:8050/report/idauthstat/loadProvinceAuthData返回的数据结构如下:
{
"data": {
"list": [
{
"totalNum": 228,
"level": 1,
"authNum": 228,
"name": "河北",
"bm": "130000",
"applyNum": 0
},
{
"totalNum": 189,
"level": 1,
"authNum": 189,
"name": "内蒙古",
"bm": "150000",
"applyNum": 0
},
{
"totalNum": 356,
"level": 1,
"authNum": 356,
"name": "辽宁",
"bm": "210000",
"applyNum": 0
},
{
"totalNum": 798,
"level": 1,
"authNum": 662,
"name": "吉林",
"bm": "220000",
"applyNum": 136
},
{
"totalNum": 1260,
"level": 2,
"authNum": 1260,
"name": "上海",
"bm": "310000",
"applyNum": 0
},
{
"totalNum": 985,
"level": 2,
"authNum": 0,
"name": "福建",
"bm": "350000",
"applyNum": 985
},
{
"totalNum": 1006,
"level": 2,
"authNum": 0,
"name": "江西",
"bm": "360000",
"applyNum": 1006
},
{
"totalNum": 1209,
"level": 2,
"authNum": 0,
"name": "山东",
"bm": "370000",
"applyNum": 1209
},
{
"totalNum": 100,
"level": 1,
"authNum": 0,
"name": "湖北",
"bm": "420000",
"applyNum": 100
},
{
"totalNum": 1725,
"level": 2,
"authNum": 1725,
"name": "湖南",
"bm": "430000",
"applyNum": 0
},
{
"totalNum": 896,
"level": 1,
"authNum": 0,
"name": "广东",
"bm": "440000",
"applyNum": 896
},
{
"totalNum": 625,
"level": 1,
"authNum": 489,
"name": "重庆",
"bm": "500000",
"applyNum": 136
},
{
"totalNum": 789,
"level": 1,
"authNum": 0,
"name": "四川",
"bm": "510000",
"applyNum": 789
},
{
"totalNum": 623,
"level": 1,
"authNum": 623,
"name": "陕西",
"bm": "610000",
"applyNum": 0
},
{
"totalNum": 1024,
"level": 2,
"authNum": 0,
"name": "新疆",
"bm": "650000",
"applyNum": 1024
},
{
"totalNum": 420,
"level": 1,
"authNum": 420,
"name": "台湾",
"bm": "710000",
"applyNum": 0
},
{
"totalNum": 876,
"level": 1,
"authNum": 876,
"name": "香港",
"bm": "810000",
"applyNum": 0
}
]
},
"msg": "操作成功",
"success": true,
"code": "I000000",
"total": null
}
统计完成,可参考