后台查询到前台所需,数据结构转换的通用方法(二) 动态增加返回字段-字段增强

背景:

(一)

前台所需的数据结构和后台sql查询的数据结构一般不一致,该情况就涉及到了数据结构的转换,往往很多接口的查询都是固定两种数据结构的转化,这个时候就可以把这种转化关系抽离成一个通用的方法,避免大量的重复代码

(二)

有时我们数据库中有很多原始数据列,每个数据列都是可以衍生出增速字段,增速=(今年数据-上一年数据)/上一年的数据,需求总是在变化的,你无法知道下一刻你需要增加的是那一个数据列的增速字段,然而增加增加增速数据列,会增加大量的冗余字段.

在通常情况下,增速是可以通过数据计算出来的,为此,我在(一)的基础上增加了动态增加增速字段,避免大量的冗余,需求的改变,也只需要通过简单的配置即可以完成,避免重复的开发工作

前台数据结构:

{
year:[2010,2011,2012],
column1:[value,value,value],
column2:[value,value,value],
column3:[value,value,value],
column1_speed:[value,value,value]
}

column1_spped:为动态增加的字段

后台数据结构:

id    year    column1    column2    column3
1     2010    value      value      value
2     2011    value      value      value
3     2012    value      value      value
4     2013    value      value      value

实现:

使用List<Map<String,Object>> 接收后台sql查询数据

select year,column1,column2,column3 from test where area_code = 110000 and year>=2010 and year <=2013

year 返回时不可重复

Set<String>去重列名集合作为参数

代码:

/**
	 * 转化数据结构返回给前端 ,该方法会少传最早的一年数据给前端
	 * @param results 原始数据结构
	 * @param addSpeedSet 用于动态增加增速字段的容器
	 * @return 新的数据结构{a:[],b:[]...}
	 */
	public Map<String, Object> transfDataStruct(List<Map<String, Object>> results,Set<String> addSpeedSet) {
		//key:{static_year:value}  管理引用的容器
		Map<String,Map<Integer,Object>> manager = new HashMap<String,Map<Integer,Object>>();
		Set<String> keys;
		Integer staticYear;
		//static_year:value(具体的值)
		Map<Integer,Object> yearValue;
		Object value;
		List<Integer> yearList = new ArrayList<Integer>();
		for (Map<String, Object> map : results) {
			keys = map.keySet();
			staticYear = Integer.parseInt(map.get("static_year").toString());
			yearList.add(staticYear);
			for (String key : keys) {
				if("static_year".equals(key)) {
					continue;
				}
				yearValue = manager.get(key);
				if(yearValue==null) {
					yearValue = new HashMap<Integer,Object>();
					manager.put(key, yearValue);
				}
				value = map.get(key);
				yearValue.put(staticYear, value);
			}
		}
		if(!yearList.isEmpty()) {
			//让年份降序排列
			Collections.sort(yearList);
			//定义结果集
			Map<String,Object> result = new HashMap<String,Object>();
			result.put("static_year", yearList);
			List<Object> resultList;
					
			
			//定义动态增加的集合
			List<Float> speedList;
			//计数
			int count;
			//上一年的数值
			BigDecimal lastValue = null;
			//现在的数值
			BigDecimal nowValue;
			
			//最近的一年
			Integer earliestYear = yearList.get(0);
			
			//封装结果集
			Set<String> managerKeys = manager.keySet();
 			for (String key : managerKeys) {
 				resultList = new ArrayList<Object>();
 				result.put(key, resultList);
 				yearValue = manager.get(key);
 				
 				//动态增加返回字段 值集合
 				if(addSpeedSet!=null&&addSpeedSet.contains(key)) {
 					count = 0;
 					speedList = new ArrayList<Float>();
 					result.put(key+"_addspeed", speedList);
 					for (Integer year : yearList) {
 						count++;
 						value = yearValue.get(year);
 						if(count==1) {
 							//以BigDecimal形式存储上一次的值
 							if(value==null) {
 	 							lastValue =  new BigDecimal(0);
 	 						}else {
 	 							lastValue =new BigDecimal(value.toString());
 	 						}
 						}else {
 							//以BigDecimal形式存储当前的值
 							if(value==null) {
 								nowValue =  new BigDecimal(0);
 	 						}else {
 	 							nowValue =new BigDecimal(value.toString());
 	 						}
 							//无法计算则增速为0
 							if(lastValue.equals(BigDecimal.ZERO)||nowValue.equals(BigDecimal.ZERO)) {
 								speedList.add(0f);
 								//保留下一次的值
 								lastValue = nowValue;
 							}else {
 								//(当前值-上一次的值)/上一次的值    保留4位有效小数
 								speedList.add(((nowValue.subtract(lastValue)).divide(lastValue,4,BigDecimal.ROUND_HALF_UP)).floatValue());
 								//保留上一次的值
 								lastValue = nowValue;
 							}
 						}
 					}
 				}
 				
				for (Integer year : yearList) {
					//跳过最早一年
					if(year==earliestYear) {
						continue;
					}
					
					value = yearValue.get(year);
					resultList.add(value);
					
					
				}
			}
 			//清除最近的一年数据
			yearList.remove(0);
			
 			return result;
		}
		return null;
	}

测试:

public static void main(String[] args) {
		MainTest test = new MainTest();
		List<Map<String,Object>> results = new ArrayList<Map<String,Object>>();
		Map<String,Object> result0 = new HashMap<String,Object>();
		results.add(result0);
		result0.put("static_year", 2009);
		result0.put("column1", 5);
		result0.put("column2", 6);
		result0.put("column3", 7);
		Map<String,Object> result1 = new HashMap<String,Object>();
		results.add(result1);
		result1.put("static_year", 2010);
		result1.put("column1", 15);
		result1.put("column2", 16);
		result1.put("column3", 17);
		Map<String,Object> result2 = new HashMap<String,Object>();
		results.add(result2);
		result2.put("static_year", 2011);
		result2.put("column1", 151);
		result2.put("column2", 161);
		result2.put("column3", 171);
		Map<String,Object> result3 = new HashMap<String,Object>();
		results.add(result3);
		result3.put("static_year", 2012);
		result3.put("column1", 1511);
		result3.put("column2", 1611);
		result3.put("column3", 1711);
		
		Set<String> addSpeedSet = new HashSet<String>();
		addSpeedSet.add("column1");
		addSpeedSet.add("column2");
		Map<String, Object> transfDataStruct = test.transfDataStruct(results,addSpeedSet);
		System.out.println(transfDataStruct);
	}

结果:

{column1=[15, 151, 1511], column1_addspeed=[2.0, 9.0667, 9.0066], static_year=[2010, 2011, 2012], column3=[17, 171, 1711], column2=[16, 161, 1611], column2_addspeed=[1.6667, 9.0625, 9.0062]}


后言:

_addspeed为后缀,可以动态的传参数指定,该方法的使用,必须要保证年份是连续的,不连续的情况,需要添加年份保证,连续后值补0或null即可,为了保证计算的顺利,需要往前多查询一年的数据,例如前台需要2010-2016年数据,后台sql查询需要查询2009-2016年数据,通用方法会自动去除2009年的数据,往前一年的数据是为了保证增速计算的必要条件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值