2019-11-22 記一次BeanUtils的優(yōu)化

業(yè)務(wù)中存在大量的request -> domin -> response的類型轉(zhuǎn)換
由于懶,不想寫這么多參數(shù)賦值损同,所以有了以下

為了方便寫一個(gè)反射方法

public static <F, T> T reflectionAttr(F f, Class<T> t) {
        try {
            Field[] fields1 = f.getClass().getDeclaredFields();
            T t1 = t.getDeclaredConstructor().newInstance();
            Field[] fields2 = t1.getClass().getDeclaredFields();
            for (Field f1 : fields1) {
                for (Field f2 : fields2) {
                    if (f1.getName().equals(f2.getName())) {
                        handler(f1, f2, f, t1);
                    }
                }
            }
            return t1;
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
        }
        return null;
    }

    private static <F, T> void handler(Field f1, Field f2, F f, T t1) throws Exception {
        Class<?> type = f1.getType();
        if (type.isEnum()) {
            //處理枚舉
            Object[] enumConstants = f2.getType().getEnumConstants();
            for (Object ob : enumConstants) {
                if (ob.toString().equals(f1.get(f).toString())) {
                    f2.set(t1, ob);
                }
            }
        } else if (type == ObjectId.class) {
            //處理objectId
            f2.set(t1, f1.get(f).toString());
        } else {
            f2.set(t1, f1.get(f));
        }
    }

優(yōu)勢(shì):所有類中參數(shù)名一樣的值都可以直接賦值
缺點(diǎn):由于使用反射+大量for循環(huán) 在重復(fù)百萬次時(shí)速度差10-20倍

考慮其它方案:
代碼生成:通過模板生成對(duì)應(yīng)的方法
核心組件velocity
流程:
1.創(chuàng)建模板
2.加載模塊
3.加載數(shù)據(jù)
4.生成代碼

記一個(gè)經(jīng)驗(yàn):******
在創(chuàng)建模板后茂卦,生成的代碼的存在對(duì)不齊的問題组哩。即处渣,如何按自己的想法創(chuàng)建格式規(guī)范的代碼而咆;
在經(jīng)過10多次調(diào)試之后~~
理論上來說,你在模板里怎么寫就會(huì)生成對(duì)應(yīng)格式的代碼
但是在使用for循環(huán)悠瞬,if判斷時(shí)涯捻,要了解到,這些特殊字符前的符號(hào)也是站位的障癌,而這些也是造成對(duì)不齊最大的原因,盡可能將for,if頂格寫康辑,需要追加的字符串前需要多少空格或者tab就直接加即可轿亮;
下面是一個(gè)包含增刪改查的service模板

/**
 * @author ${author}
 */
public class ${className}Service {
    @Inject
    Repository<${className}> ${classname}Repository;

    public Create${className}Response create(Create${className}Request request) {
        ${className} ${classname} = new ${className}();
#foreach ($column in $columns)#if($column.attrType == "LocalDateTime")
        ${classname}.${column.attrname} = LocalDateTime.now();
#elseif($column.attrType == "LocalDate")
        ${classname}.${column.attrname} = LocalDate.now();
#elseif($column.extra == "auto_increment")
#elseif($column.dataType=="enum")
        ${classname}.${column.attrname} = Enum.valueOf(${column.attrName}.class, request.${column.attrname}.toString());
#else
        ${classname}.${column.attrname} = request.${column.attrname};
#end
#end
        ${classname}.id = ${classname}Repository.insert(${classname}).orElseThrow(() -> new RuntimeException("create ${classname} failed"));
        Create${className}Response create${className}Response = new Create${className}Response();
#foreach ($column in $columns)#if($column.dataType=="enum")
        create${className}Response.${column.attrname} = Enum.valueOf(${column.attrName}View.class, ${classname}.${column.attrname}.toString());
#else
        create${className}Response.${column.attrname} = ${classname}.${column.attrname};
#end
#end
        return create${className}Response;
    }

    private ${className} get(Long id) {
        return ${classname}Repository.get(id).orElseThrow(() -> new NotFoundException("${classname} not found"));
    }

    public Update${className}Response update(Long id, Update${className}Request request) {
        ${className} ${classname} = get(id);
#foreach ($column in $columns)#if($column.attrname.indexOf("created")!=-1)
#elseif($column.attrType == "LocalDate")
        ${classname}.${column.attrname} = LocalDate.now();
#elseif($column.extra == "auto_increment")
#elseif($column.attrType == "LocalDateTime")
        ${classname}.${column.attrname} = LocalDateTime.now();
#elseif($column.dataType=="enum")
        ${classname}.${column.attrname} = Enum.valueOf(${column.attrName}.class, request.${column.attrname}.toString());
#else
        ${classname}.${column.attrname} = request.${column.attrname};
#end
#end
        ${classname}Repository.update(${classname});
        Update${className}Response update${className}Response = new Update${className}Response();
#foreach ($column in $columns)#if($column.dataType=="enum")
        update${className}Response.${column.attrname} = Enum.valueOf(${column.attrName}View.class, ${classname}.${column.attrname}.toString());
#else
        update${className}Response.${column.attrname} = ${classname}.${column.attrname};
#end
#end
        return update${className}Response;
    }

    public Get${className}Response getView(Long id) {
        ${className} ${classname} = get(id);
        Get${className}Response get${className}Response = new Get${className}Response();
#foreach ($column in $columns)#if($column.dataType=="enum")
        get${className}Response.${column.attrname} = Enum.valueOf(${column.attrName}View.class, ${classname}.${column.attrname}.toString());
#else
        get${className}Response.${column.attrname} = ${classname}.${column.attrname};
#end
#end
        return get${className}Response;
    }

    public Search${className}Response search(Search${className}Request request) {
        Query<${className}> query = ${classname}Repository.select();
        query.skip(request.skip);
        query.limit(request.limit);

        Search${className}Response search${className}Response = new Search${className}Response();
        search${className}Response.total = query.count();
        search${className}Response.${tableName} = query.fetch()
            .stream().map(${classname} -> {
                Search${className}Response.${className} search${className} = new Search${className}Response.${className}();
#foreach ($column in $columns)#if($column.dataType=="enum")
                Search${className}Response.${column.attrname} = Enum.valueOf(${column.attrName}View.class, ${classname}.${column.attrname}.toString());
#else
                Search${className}Response.${column.attrname} = ${classname}.${column.attrname};
#end
#end
                return search${className};
            }).collect(Collectors.toList());
        return search${className}Response;
    }

    public void delete(Long id) {
        get(id);
        ${classname}Repository.delete(id);
    }
}

經(jīng)驗(yàn)2:剛開始調(diào)試模板的,總要重啟項(xiàng)目才能重新加載励七,在idea中加如jrebel插件后,每次改完模板奔缠,點(diǎn)擊build即可,不用重啟項(xiàng)目校哎,加快調(diào)式速度

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贬蛙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子阳准,更是在濱河造成了極大的恐慌,老刑警劉巖讼稚,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锐想,死亡現(xiàn)場(chǎng)離奇詭異帮寻,居然都是意外死亡赠摇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門烫罩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來洽故,“玉大人,你說我怎么就攤上這事隘弊』氖剩” “怎么了?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長舅列。 經(jīng)常有香客問我卧蜓,道長帐要,這世上最難降的妖魔是什么弥奸? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任盛霎,我火速辦了婚禮,結(jié)果婚禮上愤炸,老公的妹妹穿的比我還像新娘规个。我一直安慰自己姓建,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布速兔。 她就那樣靜靜地躺著活玲,像睡著了一般。 火紅的嫁衣襯著肌膚如雪屑柔。 梳的紋絲不亂的頭發(fā)上珍剑,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音唧瘾,去河邊找鬼别凤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛规哪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蝠嘉,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼杯巨,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了杜恰?” 一聲冷哼從身側(cè)響起仍源,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎檬寂,沒想到半個(gè)月后戳表,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體昼伴,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡镣屹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年女蜈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伪窖。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡覆山,死狀恐怖竹伸,靈堂內(nèi)的尸體忽然破棺而出簇宽,到底是詐尸還是另有隱情,我是刑警寧澤譬嚣,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布钞它,位于F島的核電站,受9級(jí)特大地震影響尼桶,放射性物質(zhì)發(fā)生泄漏耻卡。R本人自食惡果不足惜疯汁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谤碳。 院中可真熱鬧,春花似錦瘸羡、人聲如沸搓茬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至粘昨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間芭析,已是汗流浹背吞瞪。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留进统,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓螟碎,卻偏偏與公主長得像迹栓,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子克伊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355