好久沒有寫技術(shù)文章了颅拦,那就重新?lián)炱饋恚瑥慕裉扉_始教藻,分享這段時間的收獲吧
其實很多時候距帅,我們只需要魚,而不是漁怖竭,吶锥债,給你魚陡蝇。
這次的分享主題是日常開發(fā)中痊臭,關(guān)于ID轉(zhuǎn)Name的問題哮肚,常見的處理就兩個方案:
- 后端直接轉(zhuǎn)換,前端只負責顯示
- 前端轉(zhuǎn)換(常見的vue 過濾器等)广匙,后臺不做任何處理
那么在什么時候應(yīng)該選擇什么方案呢允趟,一般來講會根據(jù)待轉(zhuǎn)換數(shù)據(jù)的數(shù)量來決定,5k條以內(nèi)兩個方案都沒有問題鸦致,但是數(shù)據(jù)量太大了之后
再選擇前端轉(zhuǎn)換的方案就會出現(xiàn)明顯的卡頓潮剪,和加載緩慢的問題,所以會選擇后臺來處理分唾,今天就給大家一個做好的魚抗碰,拿好了,開始發(fā)了
哈~
如圖绽乔,思路很簡單弧蝇,把工具當做一個容器,容器只提供兩個方法:
- 方法一用來接收數(shù)據(jù)源折砸;
- 方法二用來id轉(zhuǎn)換成name
先看使用的例子吧:
帶轉(zhuǎn)換實體:
import java.util.Date;
@Data
public class DemoEntity {
//默認轉(zhuǎn)換模式看疗,轉(zhuǎn)換到新的字段,默認字段名:原屬性名+“_str”
@IdToName
private Integer aId;
//轉(zhuǎn)換覆蓋原屬性
@IdToName(NewField = false)
private Integer bId;
//轉(zhuǎn)換到新的字段睦授,新字段名為 "cId_str"
@IdToName(Alias = "cId_str")
private Integer cId;
//格式化時間两芳,默認格式為 "yyyy-MM-dd"
@IdToName(DateFormat = true)
private Date startTime;
//格式化時間,格式為 "yyyy-MM-dd HH:mm:ss"
@IdToName(DateFormat = true, FormatStr = "yyyy-MM-dd HH:mm:ss")
private Date endTime;
}
測試方法:
public static void main(String[] args) {
//1去枷、準備數(shù)據(jù)源:
Map<Object, Object> dataSource = new HashMap<>(1 << 5);
dataSource.put(1, "1a名稱");
dataSource.put(2, "2b名稱");
dataSource.put(3, "3c名稱");
IdToNameUtil idToNameUtil = new IdToNameUtil();
//2怖辆、導入數(shù)據(jù)源
idToNameUtil.importSourceData(dataSource);
//3、待轉(zhuǎn)換實體對象
DemoEntity demoEntity = new DemoEntity();
demoEntity.setAId(1);
demoEntity.setBId(2);
demoEntity.setCId(3);
demoEntity.setStartTime(new Date());
demoEntity.setEndTime(new Date());
List<Object> list = new ArrayList<>();
list.add(demoEntity);
//4删顶、轉(zhuǎn)換實體
System.out.println(idToNameUtil.transportIdToName(list).toString());
}
測試結(jié)果:
[{aId_str=1a名稱, startTime_str=2019-08-23, cId_str=3c名稱, startTime=Fri Aug 23 11:24:30 CST 2019, endTime=Fri Aug 23 11:24:30 CST 2019, endTime_str=2019-08-23 11:24:30, AId=1, BId=2, bId=2b名稱, CId=3}]
使用很簡單疗隶,看完例子應(yīng)該就可以上手了,嘗試著寫下吧翼闹;
對了斑鼻,轉(zhuǎn)換10w數(shù)據(jù)的耗時在100ms+
下面就是具體的實現(xiàn),更簡單猎荠,一個自定義注解一個工具類坚弱,導入到項目就可以直接開始使用:
- 自定義注解:
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface IdToName {
/**
* 是否生成一個新的字段
*
* @return
*/
boolean NewField() default true;
/**
* 字段別名
*
* @return
*/
String Alias() default "";
/**
* 是否格式化時間
*
* @return
*/
boolean DateFormat() default false;
/**
* 時間格式(d:yyyy-MM-dd | s:yyyy-MM-dd HH:mm:ss)
*
* @return
*/
String FormatStr() default "yyyy-MM-dd";
}
- 轉(zhuǎn)換工具類:
import com.google.common.collect.Maps;
import com.hd.bizexpansion.annotation.IdToName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* id轉(zhuǎn)name工具類
*
* @author wang_yw
* @version 0.1
*/
@Component
public class IdToNameUtil {
private final Logger logger = LoggerFactory.getLogger(IdToNameUtil.class);
private Map<Object, Object> sourceData = new HashMap<>();
/**
* 導入數(shù)據(jù)源
*
* @param sourceDataItem
*/
public void importSourceData(Map<Object, Object> sourceDataItem) {
this.sourceData.putAll(sourceDataItem);
}
/**
* 轉(zhuǎn)換方法
*
* @param items
* @return
*/
public List<Object> transportIdToName(List<Object> items) {
SimpleDateFormat sdf_d = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat sdf_s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
if (this.sourceData.isEmpty() || items == null || items.isEmpty()) {
logger.warn("數(shù)據(jù)源為空,或者原數(shù)據(jù)為空");
}
//提前初始化結(jié)果集关摇,長度等于參數(shù)數(shù)組避免長度自增浪費資源
List<Object> results = new ArrayList<>(items.size());
//遍歷參數(shù)對象荒叶,開始id-name的翻譯
for (Object object : items) {
Map<String, Object> item_map = this.beanToMap(object);
Field[] fields = object.getClass().getDeclaredFields();
for (Field field : fields) {
//如果包含注解進行處理
if (field.isAnnotationPresent(IdToName.class)) {
IdToName idToName = field.getAnnotation(IdToName.class);
field.setAccessible(true);
try {
if (field.get(object) == null) {
continue;
}
//類屬性別名
String alias = idToName.Alias();
//新屬性名
String newFieldName = StringUtils.isEmpty(alias) ? field.getName() + "_str" : alias;
//如果是時間需要格式化
if (idToName.DateFormat()) {
if ("yyyy-MM-dd".equals(idToName.FormatStr())) {
item_map.put(newFieldName, sdf_d.format((Date) field.get(object)));
} else if ("yyyy-MM-dd HH:mm:ss".equals(idToName.FormatStr())) {
item_map.put(newFieldName, sdf_s.format((Date) field.get(object)));
}
continue;
}
if (idToName.NewField()) {
item_map.put(newFieldName, sourceData.get(field.get(object)));
} else {
item_map.put(field.getName(), sourceData.get(field.get(object)));
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
results.add(item_map);
}
return results;
}
/**
* 對象轉(zhuǎn)map
*
* @param bean
* @return
*/
private Map<String, Object> beanToMap(Object bean) {
Map<String, Object> map = Maps.newHashMap();
if (bean != null) {
BeanMap beanMap = BeanMap.create(bean);
for (Object key : beanMap.keySet()) {
map.put(String.valueOf(key), beanMap.get(key));
}
}
return map;
}
}
其實很多時候,我們只需要魚输虱,而不是漁些楣,吶,給你魚。
TO BE CONTINUE !