Mybatis自定義攔截器刻伊,處理通用接口

在日常開發(fā)業(yè)務(wù)場景中,經(jīng)常要遇到對 實體進行通用性操作蛾茉,如:

  1. 進行持久化時谦炬,出現(xiàn)的保存 創(chuàng)建人信息
  2. 更新數(shù)據(jù)時候节沦,通用更新 操作人信息
  3. 指定接口自定義主鍵甫贯,等
    為了解決這類問題赔桌,可以采用AOP 也可以采用攔截器疾党,以下是采用MyBatis攔截器進行實現(xiàn)的
設(shè)置通用實體參數(shù)
@Data
public class BaseEntity {

    @TableId
    private String id;

    private Date createTime;

    /**
     *  刪除狀態(tài):
     *  1 : 已刪除
     *  0 :未刪除
     */
    @Column(nullable = false)
    private Integer isDeleted;
}

@Data
@MappedSuperclass
public class CommonBaseEntity extends BaseEntity implements CreatorSetterImpl, UpdaterSetterImpl {

    /**
     *  創(chuàng)建人ID
     */
    private String creatorId;

    /**
     *  創(chuàng)建人姓名
     */
    private String creatorName;

    /**
     *  最后更新人ID
     */
    private String updaterId;

    /**
     *  最后更新人姓名
     */
    private String updaterName;

    /**
     *  最后更新時間
     */
    private Date updateTime;

}

創(chuàng)建用戶接口 CreatorSetterImpl
public interface CreatorSetterImpl {

    void setCreatorId(String creatorId);

    void setCreatorName(String creatorName);

}
更新用戶接口 UpdaterSetterImpl
public interface UpdaterSetterImpl {

    void setUpdaterId(String updaterId);

    void setUpdaterName(String updaterName);

    void setUpdateTime(Date updateTime);
}

編寫攔截器


/**
 * @ClassName: BaseEntityMapperInterceptor
 * @Author: ren
 * @Description:
 * @CreateTIme: 2019/7/8 0008 下午 5:26
 **/
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class BaseEntityMapperInterceptor implements Interceptor, WapperInterface {


    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        //獲取代理對象梨撞,由于注解的反射卧波,返回的為   確定類型 StatementHandler 的實例對象
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();

        //通過包裝類幽勒,把statementHandler包裝成一個可以調(diào)用反射的代理對象
        MetaObject metaObject = MetaObject.forObject(statementHandler, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY, DEFAULT_REFLECTOR_FACTORY);

        //事實上攔截到的時RoutingStatementHandler锈颗,需要調(diào)用其中的 delegate 屬性咪惠,才可以調(diào)用到  mappedStatement覆醇,然后通過反射調(diào)用獲取到mappedStatement對象
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");

        DefaultParameterHandler parameterHandler = (DefaultParameterHandler) metaObject.getValue("delegate.parameterHandler");

        //獲取查詢映射的名稱
        String id = mappedStatement.getId();
        String methodName = id.substring(id.lastIndexOf(".") + 1);

        Log4jUtils.getInstance(getClass()).debug("進行通用攔截:" + methodName);
        Object parameter = parameterHandler.getParameterObject();

        if (methodName.matches("save.*")) {
            // 配置通用變量
            initSaveMethod(parameter);
            if (parameter instanceof HashMap) {

                HashMap map = (HashMap) parameter;

                map.forEach((k, v) -> {
                    if (v instanceof Collection) {
                        Collection collection = (Collection) v;

                        collection.forEach(obj -> {
                            // 配置通用變量
                            initSaveMethod(obj);
                        });
                    }
                });

            }
        } else if (methodName.matches("update.*")) {

            initUpdateMethod(parameter);
            if (parameter instanceof HashMap) {
                HashMap map = (HashMap) parameter;

                map.forEach((k, v) -> {
                    if (v instanceof Collection) {
                        Collection collection = (Collection) v;

                        collection.forEach(obj -> {
                            // 配置通用變量
                            initUpdateMethod(obj);
                        });
                    }
                });
            }


        }

        return invocation.proceed();
    }

    /**
     * 配置通用更新方法
     *
     * @param parameter
     */
    private void initUpdateMethod(Object parameter) {
        if (parameter instanceof UpdaterSetterImpl) {
            UserEntity user = UserContext.getUserEntity();
            if (null != user) {
                UpdaterSetterImpl setter = (UpdaterSetterImpl) parameter;
                setter.setUpdaterId(user.getUserId());
                setter.setUpdaterName(user.getUsername());
                setter.setUpdateTime(new Date());
            }
        }
    }

    /**
     * 配置通用新增方法
     *
     * @param parameter
     */
    private void initSaveMethod(Object parameter) {
        if (parameter instanceof BaseEntity) {
            Log4jUtils.getInstance(getClass()).debug("配置通用持久化變量");

            BaseEntity baseEntity = (BaseEntity) parameter;
            baseEntity.setId(IdWorker.getIdStr());
            baseEntity.setIsDeleted(0);
            baseEntity.setCreateTime(new Date());
        }

        if (parameter instanceof CreatorSetterImpl) {
            Log4jUtils.getInstance(getClass()).debug("配置創(chuàng)建人信息");
            UserEntity user = UserContext.getUserEntity();
            if (null != user) {
                CreatorSetterImpl setter = (CreatorSetterImpl) parameter;
                setter.setCreatorId(user.getUserId());
                setter.setCreatorName(user.getUsername());
            }
        }
    }


    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}
在Myabtis配置中加入攔截器
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <!--配置全局變量 -->
    <settings>
        <!-- jdbc用getGeneratedKeys 獲取數(shù)據(jù)庫自增鍵值 -->
        <setting name="useGeneratedKeys" value="true" />
        <!-- 使用列別名替代列名 select name as title from table -->
        <setting name="useColumnLabel" value="true" />
        <!-- 開啟駝峰命名法: Table(create_time) ->createTime -->
        <setting name="mapUnderscoreToCamelCase" value="true" />
    </settings>

    <plugins>
        <plugin interceptor="com.example.oldguy.modules.commons.interceptors.BaseEntityMapperInterceptor"/>
        <!--<plugin interceptor="com.example.oldguy.modules.commons.interceptors.BaseEntityInterceptor"/>-->
        <plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"/>
    </plugins>

</configuration>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末落午,一起剝皮案震驚了整個濱河市溃斋,隨后出現(xiàn)的幾起案子梗劫,更是在濱河造成了極大的恐慌梳侨,老刑警劉巖猫妙,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異彼哼,居然都是意外死亡敢朱,警方通過查閱死者的電腦和手機拴签,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來岸梨,“玉大人曹阔,你說我怎么就攤上這事寂拆±炜猓” “怎么了渺蒿?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長少态。 經(jīng)常有香客問我,道長侨歉,這世上最難降的妖魔是什么幽邓? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮畸颅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘窥浪。我一直安慰自己漾脂,他們只是感情好笨鸡,可當(dāng)我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著激涤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪辱挥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天,我揣著相機與錄音,去河邊找鬼端衰。 笑死,一個胖子當(dāng)著我的面吹牛抵代,可吹牛的內(nèi)容都是我干的案腺。 我是一名探鬼主播劈榨,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼惭载,長吁一口氣:“原來是場噩夢啊……” “哼棒妨!你這毒婦竟也來了靶衍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤偷厦,失蹤者是張志新(化名)和其女友劉穎只泼,沒想到半個月后请唱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體聚至,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年片择,在試婚紗的時候發(fā)現(xiàn)自己被綠了字管。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片亡呵。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡丁逝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出铸题,到底是詐尸還是另有隱情琢感,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布暗甥,位于F島的核電站,受9級特大地震影響捉捅,放射性物質(zhì)發(fā)生泄漏撤防。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一棒口、第九天 我趴在偏房一處隱蔽的房頂上張望寄月。 院中可真熱鬧辜膝,春花似錦、人聲如沸漾肮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽克懊。三九已至忱辅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谭溉,已是汗流浹背墙懂。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扮念,地道東北人损搬。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像柜与,于是被迫代替她去往敵國和親巧勤。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,927評論 2 355

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

  • 1.JVM 堆內(nèi)存和非堆內(nèi)存 堆和非堆內(nèi)存按照官方的說法:“Java 虛擬機具有一個堆(Heap)弄匕,堆是運行時數(shù)據(jù)...
    yanzhu728閱讀 913評論 0 0
  • 1. 簡介 1.1 什么是 MyBatis 颅悉? MyBatis 是支持定制化 SQL、存儲過程以及高級映射的優(yōu)秀的...
    笨鳥慢飛閱讀 5,520評論 0 4
  • 這部分主要是開源Java EE框架方面的內(nèi)容粘茄,包括Hibernate签舞、MyBatis、Spring柒瓣、Spring ...
    雜貨鋪老板閱讀 1,385評論 0 2
  • iOS網(wǎng)絡(luò)架構(gòu)討論梳理整理中儒搭。。芙贫。 其實如果沒有APIManager這一層是沒法使用delegate的搂鲫,畢竟多個單...
    yhtang閱讀 5,192評論 1 23
  • 一 基礎(chǔ)篇 1.1 Java基礎(chǔ) 面向?qū)ο蟮奶卣鞒橄?將一類對象的共同特征總結(jié)出來構(gòu)建類的過程。繼承:對已有類的一...
    essential_note閱讀 695評論 0 0