ID轉(zhuǎn)名稱到手方案01

好久沒有寫技術(shù)文章了颅拦,那就重新?lián)炱饋恚瑥慕裉扉_始教藻,分享這段時間的收獲吧


其實很多時候距帅,我們只需要魚,而不是漁怖竭,吶锥债,給你魚陡蝇。

這次的分享主題是日常開發(fā)中痊臭,關(guān)于ID轉(zhuǎn)Name的問題哮肚,常見的處理就兩個方案:

  1. 后端直接轉(zhuǎn)換,前端只負責顯示
  2. 前端轉(zhuǎn)換(常見的vue 過濾器等)广匙,后臺不做任何處理

那么在什么時候應(yīng)該選擇什么方案呢允趟,一般來講會根據(jù)待轉(zhuǎn)換數(shù)據(jù)的數(shù)量來決定,5k條以內(nèi)兩個方案都沒有問題鸦致,但是數(shù)據(jù)量太大了之后
再選擇前端轉(zhuǎn)換的方案就會出現(xiàn)明顯的卡頓潮剪,和加載緩慢的問題,所以會選擇后臺來處理分唾,今天就給大家一個做好的魚抗碰,拿好了,開始發(fā)了
哈~


file

如圖绽乔,思路很簡單弧蝇,把工具當做一個容器,容器只提供兩個方法:

  1. 方法一用來接收數(shù)據(jù)源折砸;
  2. 方法二用來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),更簡單猎荠,一個自定義注解一個工具類坚弱,導入到項目就可以直接開始使用

  1. 自定義注解:
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";
}
  1. 轉(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 !

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末愁茁,一起剝皮案震驚了整個濱河市蚕钦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鹅很,老刑警劉巖嘶居,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異促煮,居然都是意外死亡邮屁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門菠齿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來佑吝,“玉大人,你說我怎么就攤上這事绳匀〖8颍” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵襟士,是天一觀的道長盗飒。 經(jīng)常有香客問我,道長陋桂,這世上最難降的妖魔是什么逆趣? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮嗜历,結(jié)果婚禮上宣渗,老公的妹妹穿的比我還像新娘。我一直安慰自己梨州,他們只是感情好痕囱,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著暴匠,像睡著了一般鞍恢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上每窖,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天帮掉,我揣著相機與錄音,去河邊找鬼窒典。 笑死蟆炊,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的瀑志。 我是一名探鬼主播涩搓,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼污秆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了昧甘?” 一聲冷哼從身側(cè)響起良拼,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎疾层,沒想到半個月后将饺,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贡避,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡痛黎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了刮吧。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片湖饱。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖杀捻,靈堂內(nèi)的尸體忽然破棺而出井厌,到底是詐尸還是另有隱情,我是刑警寧澤致讥,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布仅仆,位于F島的核電站,受9級特大地震影響垢袱,放射性物質(zhì)發(fā)生泄漏墓拜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一请契、第九天 我趴在偏房一處隱蔽的房頂上張望咳榜。 院中可真熱鬧,春花似錦爽锥、人聲如沸涌韩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽臣樱。三九已至,卻和暖如春腮考,著一層夾襖步出監(jiān)牢的瞬間擎淤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工秸仙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留嘴拢,地道東北人。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓寂纪,卻偏偏與公主長得像席吴,于是被迫代替她去往敵國和親赌结。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容