SSM(九) 反射的實(shí)際應(yīng)用 - 構(gòu)建日志對(duì)象

1

前言

相信做Java的童鞋或多或少都聽過反射戈咳,這也應(yīng)該是Java從入門到進(jìn)階的必經(jīng)之路己沛。

但是在我們的實(shí)際開發(fā)中直接使用它們的幾率貌似還是比較少的竹祷,(除了造輪子或者是Spring Mybatis這些框架外)疆拘。

所以這里介紹一個(gè)在實(shí)際開發(fā)中還是小有用處的反射實(shí)例寝并。

傳統(tǒng)日志

有關(guān)反射的一些基本知識(shí)就不說了箫措,可以自行Google,也可以看下反射入門衬潦。

日志相信大家都不陌生斤蔓,在實(shí)際開發(fā)中一些比較敏感的數(shù)據(jù)表我們需要對(duì)它的每一次操作都記錄下來。

先來看看傳統(tǒng)的寫法:

    @Test
    public void insertSelective() throws Exception {

        Content content = new Content() ;
        content.setContent("asdsf");
        content.setCreatedate("2016-12-09");
        contentService.insertSelective(content) ;

        ContentLog log = new ContentLog();
        log.setContentid(content.getContentid());
        log.setContent("asdsf");
        log.setCreatedate("2016-12-09");
        contentLogService.insertSelective(log);
    }

非常簡(jiǎn)單别渔,就是在保存完數(shù)據(jù)表之后再把相同的數(shù)據(jù)保存到日志表中附迷。

但是這樣有以下幾個(gè)問題:

  • 如果數(shù)據(jù)表的字段較多的話惧互,比如幾百個(gè)。那么日志表的setter()方法就得寫幾百次喇伯,還得是都寫對(duì)的情況下喊儡。
  • 如果哪天數(shù)據(jù)表的字段發(fā)生了增加,那么每個(gè)寫日志的地方都得增加該字段稻据,提高了維護(hù)的成本艾猜。

針對(duì)以上的情況就得需要反射這個(gè)主角來解決了。

利用反射構(gòu)建日志

我們先來先來看下使用反射之后對(duì)代碼所帶來的改變:

    @Test
    public void insertSelective2() throws Exception {
        Content content = new Content();
        content.setContent("你好");
        content.setContentname("1");
        content.setCreatedate("2016-09-23");

        contentService.insertSelective(content);

        ContentLog log = new ContentLog();
        CommonUtil.setLogValueModelToModel(content, log);
        contentLogService.insertSelective(log);
    }

同樣的保存日志捻悯,不管多少字段匆赃,只需要三行代碼即可解決。
而且就算之后字段發(fā)生改變寫日志這段代碼仍然不需要改動(dòng)今缚。

其實(shí)這里最主要的一個(gè)方法就是CommonUtil.setLogValueModelToModel(content, log);

來看下是如何實(shí)現(xiàn)的;

/**
     * 生成日志實(shí)體工具
     *
     * @param objectFrom
     * @param objectTo
     */
    public static void setLogValueModelToModel(Object objectFrom, Object objectTo) {
        Class<? extends Object> clazzFrom = objectFrom.getClass();
        Class<? extends Object> clazzTo = objectTo.getClass();

        for (Method toSetMethod : clazzTo.getMethods()) {
            String mName = toSetMethod.getName();
            if (mName.startsWith("set")) {
                //字段名
                String field = mName.substring(3);

                //獲取from 值
                Object value;
                try {
                    if ("LogId".equals(field)) {
                        continue;
                    }
                    Method fromGetMethod = clazzFrom.getMethod("get" + field);
                    value = fromGetMethod.invoke(objectFrom);

                    //設(shè)置值
                    toSetMethod.invoke(objectTo, value);
                } catch (NoSuchMethodException e) {
                    throw new RuntimeException(e);
                } catch (InvocationTargetException e) {
                    throw new RuntimeException(e);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

再使用之前我們首先需要構(gòu)建好主的數(shù)據(jù)表算柳,然后new一個(gè)日志表的對(duì)象。

setLogValueModelToModel()方法中:

  • 分別獲得數(shù)據(jù)表和日志表對(duì)象的類類型姓言。
  • 獲取到日志對(duì)象的所有方法集合瞬项。
  • 遍歷該集合,并拿到該方法的名稱何荚。
  • 只取其中set開頭的方法囱淋,也就是set方法。因?yàn)槲覀冃枰谘h(huán)中為日志對(duì)象的每一個(gè)字段賦值餐塘。
  • 之后截取方法名稱獲得具體的字段名稱妥衣。
  • 用之前截取的字段名稱,通過getMethod()方法返回?cái)?shù)據(jù)表中的該字段的getter方法戒傻。
  • 相當(dāng)于執(zhí)行了String content = content.getContent();
  • 執(zhí)行該方法獲得該字段具體的值税手。
  • 利用當(dāng)前循環(huán)的setter方法為日志對(duì)象的每一個(gè)字段賦值。
  • 相當(dāng)于執(zhí)行了log.setContent("asdsf");

其中字段名稱為LogId時(shí)跳出了當(dāng)前循環(huán)稠鼻,因?yàn)長(zhǎng)ogId是日志表的主鍵冈止,是不需要賦值的狂票。

當(dāng)循環(huán)結(jié)束時(shí)候齿,日志對(duì)象也就構(gòu)建完成了。之后只需要保存到數(shù)據(jù)庫中即可闺属。

總結(jié)

反射其實(shí)是非常耗資源的慌盯,再使用過程中還是要慎用。
其中對(duì)method掂器、field亚皂、constructor等對(duì)象做緩存也是很有必要的。

項(xiàng)目地址:https://github.com/crossoverJie/SSM.git

個(gè)人博客地址:http://crossoverjie.top国瓮。

GitHub地址:https://github.com/crossoverJie灭必。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末狞谱,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子禁漓,更是在濱河造成了極大的恐慌跟衅,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,843評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件播歼,死亡現(xiàn)場(chǎng)離奇詭異伶跷,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)秘狞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門叭莫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人烁试,你說我怎么就攤上這事雇初。” “怎么了减响?”我有些...
    開封第一講書人閱讀 163,187評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵抵皱,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我辩蛋,道長(zhǎng)呻畸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,264評(píng)論 1 292
  • 正文 為了忘掉前任悼院,我火速辦了婚禮伤为,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘据途。我一直安慰自己绞愚,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評(píng)論 6 390
  • 文/花漫 我一把揭開白布颖医。 她就那樣靜靜地躺著位衩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪熔萧。 梳的紋絲不亂的頭發(fā)上糖驴,一...
    開封第一講書人閱讀 51,231評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音佛致,去河邊找鬼贮缕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛俺榆,可吹牛的內(nèi)容都是我干的感昼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,116評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼罐脊,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼定嗓!你這毒婦竟也來了蜕琴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,945評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤宵溅,失蹤者是張志新(化名)和其女友劉穎奸绷,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體层玲,經(jīng)...
    沈念sama閱讀 45,367評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡号醉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了辛块。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片畔派。...
    茶點(diǎn)故事閱讀 39,754評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖润绵,靈堂內(nèi)的尸體忽然破棺而出线椰,到底是詐尸還是另有隱情,我是刑警寧澤尘盼,帶...
    沈念sama閱讀 35,458評(píng)論 5 344
  • 正文 年R本政府宣布憨愉,位于F島的核電站,受9級(jí)特大地震影響卿捎,放射性物質(zhì)發(fā)生泄漏配紫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評(píng)論 3 327
  • 文/蒙蒙 一午阵、第九天 我趴在偏房一處隱蔽的房頂上張望躺孝。 院中可真熱鬧,春花似錦底桂、人聲如沸植袍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽于个。三九已至,卻和暖如春暮顺,著一層夾襖步出監(jiān)牢的瞬間厅篓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評(píng)論 1 269
  • 我被黑心中介騙來泰國打工拖云, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留贷笛,地道東北人应又。 一個(gè)月前我還...
    沈念sama閱讀 47,797評(píng)論 2 369
  • 正文 我出身青樓宙项,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親株扛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子尤筐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評(píng)論 2 354

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