最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mybatis中攔截器的使用場景和技巧分享

 更新時(shí)間:2023年10月23日 11:40:09   作者:襄垣  
Mybatis提供了一些機(jī)制,可以允許我們在做數(shù)據(jù)庫操作的時(shí)候進(jìn)行我們額外的一些程序,當(dāng)然,這看起來并沒有JPA的EntityListener好用,本文小編將給大家詳細(xì)的介紹了Mybatis中攔截器的使用場景和技巧,需要的朋友可以參考下

場景描述

中小業(yè)務(wù)系統(tǒng)中,有時(shí)候會面臨一些比較相似的業(yè)務(wù)場景。

  • 當(dāng)XXX創(chuàng)建成功后,需要給XXX推送一條業(yè)務(wù)消息;
  • 當(dāng)XXX更新的時(shí)候,需要給XXX推送一條業(yè)務(wù)提醒;
  • 當(dāng)XXX創(chuàng)建OR更新的時(shí)候,需要將最新的數(shù)據(jù)推送到搜索引擎中,以方便其他業(yè)務(wù)系統(tǒng)在搜索引擎中能查詢到;
  • 當(dāng)XXX更新的時(shí)候,需要更新分布式緩存的XXX數(shù)據(jù);
  • ……

這些場景都有相似的特征,如下

特征描述
異步實(shí)際上與主流程關(guān)系不大,可以作為附屬流程異步執(zhí)行
事務(wù)大多在事務(wù)結(jié)束之后執(zhí)行
并行可以串行執(zhí)行,也可以并行執(zhí)行,對最終結(jié)果影響不大

Mybatis攔截器

Mybatis提供了一些機(jī)制,可以允許我們在做數(shù)據(jù)庫操作的時(shí)候進(jìn)行我們額外的一些程序。當(dāng)然,這看起來并沒有JPA的EntityListener好用。

但是通過這些機(jī)制,我們可以達(dá)成我們主要的目的,解耦合。(解耦合的好處顯而易見,我們在關(guān)注主流程業(yè)務(wù)的時(shí)候,附屬流程的業(yè)務(wù)也更容易擴(kuò)展)

下面是我們即將用到的一些簡單概念,如下

概念描述
解耦解耦的本質(zhì)就是將類之間的直接關(guān)系轉(zhuǎn)換成間接關(guān)系
觀察者模式一種行為設(shè)計(jì)模式,允許你定義一種訂閱機(jī)制,可在對象事件發(fā)生時(shí)通知多個(gè)“觀察”該對象的其他對象。
EventBus基于事件驅(qū)動(dòng),觀察者們監(jiān)聽自己感興趣的特定事件,進(jìn)行相應(yīng)的處理。

錨定事件發(fā)生

首先,我們要找到事件發(fā)生的地方,通常來說我們更愿意在業(yè)務(wù)代碼里寫

Company company = new Company();
company.setCompanyName(companyName);
companyMapper.insert(company);
// 創(chuàng)建XXX成功后,觸發(fā)了一些操作;
doSomething(company);

但是,這種方式是耦合的,我們在doSomething() 里發(fā)生的一些異常會影響到主流程,而每一次增加附屬流程的改動(dòng),都會產(chǎn)生影響范圍的蔓延。

這里,我們使用Mybatis提供的一種方式來錨定事件發(fā)生

@Component
@Intercepts( {
    @Signature(method = "update", type = Executor.class, args = {
        MappedStatement.class,
        Object.class
    })
})
public class EntityInterceptor implements Interceptor {
    private static final Logger LOGGER = LoggerFactory.getLogger(EntityInterceptor.class);

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object proceed = invocation.proceed();
        try {
            Object[] args = invocation.getArgs();
            MappedStatement ms = (MappedStatement) args[0];
            Object params = args[1];
            if (SqlCommandType.INSERT.equals(ms.getSqlCommandType())) {
                insertCommond(params);
            }
            if (SqlCommandType.UPDATE.equals(ms.getSqlCommandType())) {
                updateCommond(params);
            }
        } catch (Exception e) {
            LOGGER.warn("entity change warning: {}", e.getMessage());
        } finally {
            return proceed;
        }
    }
    
        private void insertCommond(Object params) {
        if (Objects.isNull(params)) {
            return;
        }
        // 插入Company的事件
        if (params instanceof Company) {
            Company company = (Company) params;
            CompanyEvent companyEvent =
                new CompanyEvent(CompanyEvent.TOPIC_ADD, WebUtils.getOpenId(), CompanyVo.from(company));
            SpringUtil.getApplicationContext().publishEvent(companyEvent);
            LOGGER.info("[發(fā)布事件:{}] - [事件內(nèi)容:{}]", CompanyEvent.TOPIC_ADD, JSON.toJSONString(companyEvent));
        }
    }
}

在這里,我們監(jiān)聽了MybatisExecutor對象的update方法,來監(jiān)聽對象的新增和修改。

package org.apache.ibatis.executor;

public interface Executor {

  int update(MappedStatement ms, Object parameter) throws SQLException;
}

當(dāng) Company 的 insert 事件發(fā)生時(shí),我們發(fā)布了一條 CompanyEvent 的事件。

訂閱事件

我們使用發(fā)布-訂閱模型實(shí)現(xiàn)了解耦合,針對剛才發(fā)布的 CompanyEvent 事件,我們來寫一個(gè)事件消費(fèi)者。

@Component
public class CompanyListener {

    /**
     * 監(jiān)聽事件 - 公司.
     *
     * @param companyEvent 事件.
     */
    @Lazy
    @Async
    @TransactionalEventListener(
        fallbackExecution = true,
        phase = TransactionPhase.AFTER_COMPLETION,
        classes = CompanyEvent.class)
    public void doAsync(CompanyEvent companyEvent) {
        LOGGER.info("[Company 訂閱:{}] - [開始執(zhí)行:{}]",
            companyEvent.getTopic(), JSON.toJSONString(companyVo));
    }
}

代碼中涉及到一些注解,簡單介紹下

注解介紹
@Component會注冊為Spring的一個(gè)Bean
@Lazy該方法會異步執(zhí)行
@TransactionalEventListener在事務(wù)的不同階段去觸發(fā)執(zhí)行該監(jiān)聽

我們標(biāo)注了該事件是在TransactionPhase.AFTER_COMPLETION(事務(wù)提交完成)這個(gè)事務(wù)節(jié)點(diǎn)進(jìn)行事件處理。

觀察者模式

上面使用了SpringEventListener來實(shí)現(xiàn)的事件驅(qū)動(dòng),除此之外,還可以使用GuavaEventBus、Vert.xEventBus等方式實(shí)現(xiàn)。

很多工具類提供了關(guān)于EventBus的實(shí)現(xiàn),但是使用邏輯和方式上大多大同小異。

總結(jié)

觀察者模式、監(jiān)聽模式都有利于解耦合,根據(jù)業(yè)務(wù)訴求合理的進(jìn)行開發(fā)設(shè)計(jì),能為以后的擴(kuò)展打下堅(jiān)實(shí)的基礎(chǔ)。

以上就是Mybatis中攔截器的使用場景和技巧分享的詳細(xì)內(nèi)容,更多關(guān)于Mybatis攔截器使用的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring boot集成Go-FastDFS實(shí)現(xiàn)圖片上傳刪除等功能實(shí)現(xiàn)

    Spring boot集成Go-FastDFS實(shí)現(xiàn)圖片上傳刪除等功能實(shí)現(xiàn)

    這篇文章主要介紹了Spring boot集成Go-FastDFS實(shí)現(xiàn)圖片上傳刪除等功能實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • Nacos Server部署配置全過程

    Nacos Server部署配置全過程

    本文介紹了Nacos的定義、核心功能(服務(wù)注冊、心跳、發(fā)現(xiàn)、健康檢查等)、單機(jī)和集群部署步驟,以及客戶端服務(wù)的搭建與配置,旨在幫助用戶快速了解和使用Nacos進(jìn)行服務(wù)治理和配置管理
    2025-10-10
  • java開發(fā)之讀寫txt文件操作的實(shí)現(xiàn)

    java開發(fā)之讀寫txt文件操作的實(shí)現(xiàn)

    本篇文章介紹了,java開發(fā)之讀寫txt文件操作的實(shí)現(xiàn)。需要的朋友參考下
    2013-05-05
  • java 數(shù)據(jù)類型有哪些取值范圍多少

    java 數(shù)據(jù)類型有哪些取值范圍多少

    這篇文章主要介紹了java 數(shù)據(jù)類型有哪些取值范圍多少的相關(guān)資料,網(wǎng)上關(guān)于java 數(shù)據(jù)類型的資料有很多,不夠全面,這里就整理下,需要的朋友可以參考下
    2017-01-01
  • Java?Ribbon與openfeign區(qū)別和用法講解

    Java?Ribbon與openfeign區(qū)別和用法講解

    Ribbon是基于Netflix?Ribbon實(shí)現(xiàn)的一套客戶端負(fù)載均衡的工具,主要功能是提供客戶端的軟件負(fù)載均衡算法和服務(wù)調(diào)用。openfeign對Feign進(jìn)行了增強(qiáng),使其支持Spring MVC注解,另外還整合了Ribbon和Nacos,從而使得Feign的使用更加方便
    2022-08-08
  • idea遠(yuǎn)程調(diào)試spark的步驟講解

    idea遠(yuǎn)程調(diào)試spark的步驟講解

    今天小編就為大家分享一篇關(guān)于idea遠(yuǎn)程調(diào)試spark的步驟講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • SpringBoot 集成 Statemachine的實(shí)戰(zhàn)指南

    SpringBoot 集成 Statemachine的實(shí)戰(zhàn)指南

    本文介紹了Spring State Machine框架的基本概念、核心特性、注解驅(qū)動(dòng)開發(fā)方式以及如何在Spring Boot項(xiàng)目中集成狀態(tài)機(jī),通過狀態(tài)機(jī),可以有效地管理復(fù)雜的狀態(tài)流轉(zhuǎn)邏輯,文章還討論了狀態(tài)機(jī)的持久化問題,并提供了一個(gè)自定義持久化實(shí)現(xiàn)的示例,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • spring-boot-starter-security的簡單使用方式

    spring-boot-starter-security的簡單使用方式

    文章介紹了三種使用Spring Boot Security的方法:基于配置文件、基于配置類和基于注解的方式,通過這些方法,可以實(shí)現(xiàn)對Web應(yīng)用的權(quán)限控制,確保只有授權(quán)用戶才能訪問特定資源
    2024-11-11
  • 解決mybatis-plus3.1.1版本使用lambda表達(dá)式查詢報(bào)錯(cuò)的方法

    解決mybatis-plus3.1.1版本使用lambda表達(dá)式查詢報(bào)錯(cuò)的方法

    這篇文章主要介紹了解決mybatis-plus3.1.1版本使用lambda表達(dá)式查詢報(bào)錯(cuò)的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • SpringBoot項(xiàng)目如何使用多線程執(zhí)行定時(shí)任務(wù)

    SpringBoot項(xiàng)目如何使用多線程執(zhí)行定時(shí)任務(wù)

    在SpringBoot項(xiàng)目中使用多線程執(zhí)行定時(shí)任務(wù),可以避免一個(gè)耗時(shí)任務(wù)影響其他任務(wù),通過配置線程池任務(wù)調(diào)度器,Spring會自動(dòng)使用多線程執(zhí)行定時(shí)任務(wù)
    2025-01-01

最新評論

卓资县| 龙江县| 宜君县| 阿拉善右旗| 左云县| 蒙自县| 增城市| 隆林| 肥东县| 广灵县| 子洲县| 敦煌市| 岱山县| 元阳县| 龙游县| 广汉市| 武山县| 黄大仙区| 来宾市| 黔东| 福鼎市| 龙游县| 泰宁县| 兴文县| 吉林省| 琼结县| 舟山市| 嘉禾县| 鄂托克前旗| 嘉义县| 安远县| 绥宁县| 南陵县| 济宁市| 临汾市| 涞源县| 西宁市| 永吉县| 林口县| 通道| 双牌县|