成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

MyBatis 攔截器,帶你輕松搞定數(shù)據(jù)脫敏!

數(shù)據(jù)庫 其他數(shù)據(jù)庫
MyBatis 攔截器是一種插件機(jī)制,用于在 MyBatis 執(zhí)行 SQL 語句時(shí)對(duì)其進(jìn)行攔截、修改或增強(qiáng)。攔截器可以插入到 MyBatis 的執(zhí)行過程中的不同位置,從而實(shí)現(xiàn)自定義的行為,例如記錄日志、修改 SQL 查詢、增強(qiáng)性能等。

1. 引言

1.1 什么是 MyBatis 攔截器

MyBatis 攔截器是一種插件機(jī)制,用于在 MyBatis 執(zhí)行 SQL 語句時(shí)對(duì)其進(jìn)行攔截、修改或增強(qiáng)。攔截器可以插入到 MyBatis 的執(zhí)行過程中的不同位置,從而實(shí)現(xiàn)自定義的行為,例如記錄日志、修改 SQL 查詢、增強(qiáng)性能等。

  • 定義:MyBatis 攔截器是一種自定義插件,可以通過它攔截 MyBatis 核心組件(如 Executor、StatementHandler、ParameterHandler、ResultSetHandler)的方法調(diào)用。通過攔截器,我們可以在不修改 MyBatis 源碼的情況下,改變其行為或增強(qiáng)其功能。
  • 功能:

修改 SQL 語句,例如根據(jù)某些業(yè)務(wù)規(guī)則動(dòng)態(tài)拼接 SQL。

記錄 SQL 執(zhí)行日志、性能監(jiān)控,統(tǒng)計(jì)執(zhí)行時(shí)間等。

控制事務(wù)或?qū)崿F(xiàn)緩存邏輯等。

1.2 為什么使用攔截器

使用 MyBatis 攔截器的主要原因是需要在不修改核心代碼的情況下,靈活地?cái)U(kuò)展 MyBatis 的功能。常見的應(yīng)用場景包括:

  • 日志記錄:通過攔截器記錄每個(gè) SQL 語句的執(zhí)行情況,包括 SQL 本身、執(zhí)行時(shí)間、返回結(jié)果等信息,用于后期分析和調(diào)試。
  • SQL 性能監(jiān)控:攔截器可以用于統(tǒng)計(jì) SQL 執(zhí)行的時(shí)間,從而評(píng)估 SQL 的性能。長時(shí)間執(zhí)行的 SQL 可以被識(shí)別出來,作為性能優(yōu)化的目標(biāo)。
  • 修改 SQL 語句:通過攔截器可以動(dòng)態(tài)修改 SQL 語句,例如,在查詢中動(dòng)態(tài)插入條件、修改排序規(guī)則,或者添加分頁邏輯。
  • 事務(wù)控制:在執(zhí)行 SQL 操作之前、之后,或者在某些異常發(fā)生時(shí),攔截器可以用來增強(qiáng)事務(wù)管理。

2. MyBatis 攔截器工作原理

2.1 攔截器的核心概念

MyBatis 攔截器工作時(shí),核心組件是 Invocation、Interceptor、Method 和 Target 對(duì)象等:

  • Interceptor:這是所有自定義攔截器的接口,MyBatis 會(huì)根據(jù)配置找到并調(diào)用實(shí)現(xiàn)該接口的類。
  • Invocation:封裝了方法調(diào)用的對(duì)象,它包含了目標(biāo)方法的信息以及方法的參數(shù)。通過 Invocation 對(duì)象,我們可以對(duì)方法的執(zhí)行進(jìn)行控制。
  • Method:表示目標(biāo)方法,它是通過反射來獲取的。
  • Target:表示目標(biāo)對(duì)象,它是被攔截的對(duì)象。例如,Executor、StatementHandler 等都是目標(biāo)對(duì)象,攔截器會(huì)通過 Target 對(duì)象來訪問和控制這些對(duì)象的行為。

2.2 攔截器的生命周期

MyBatis 中,攔截器的生命周期通常包含三個(gè)階段:

  1. 插件初始化:當(dāng) MyBatis 啟動(dòng)時(shí),它會(huì)加載并初始化所有配置的攔截器。這時(shí),攔截器會(huì)準(zhǔn)備好攔截邏輯。
  2. 攔截執(zhí)行:當(dāng) MyBatis 執(zhí)行某個(gè) SQL 語句時(shí),會(huì)觸發(fā)攔截器的 intercept() 方法,這時(shí)攔截器會(huì)獲取執(zhí)行方法的參數(shù),可以進(jìn)行修改、增強(qiáng)或替換方法的執(zhí)行。
  3. 插件銷毀:攔截器在 MyBatis 銷毀時(shí)會(huì)清理資源,釋放占用的內(nèi)存或線程等。

2.3 目標(biāo)對(duì)象和方法

在 MyBatis 中,主要有四個(gè)目標(biāo)對(duì)象可以被攔截:

  • Executor:執(zhí)行 SQL 語句的核心對(duì)象。它的 update()、query() 等方法負(fù)責(zé)執(zhí)行實(shí)際的增、刪、改、查操作。
  • StatementHandler:處理 SQL 語句的對(duì)象。它負(fù)責(zé)將 SQL 語句和參數(shù)綁定,并將其傳遞給數(shù)據(jù)庫。
  • ResultSetHandler:處理 SQL 查詢結(jié)果的對(duì)象。它負(fù)責(zé)將從數(shù)據(jù)庫返回的 ResultSet 轉(zhuǎn)換為 Java 對(duì)象。
  • ParameterHandler:處理 SQL 參數(shù)綁定的對(duì)象。它負(fù)責(zé)將參數(shù)設(shè)置到 SQL 語句中。

3. MyBatis 攔截器的實(shí)現(xiàn)

這里小編會(huì)分享工作中實(shí)際的案例: 數(shù)據(jù)脫敏。

3.1 自定義脫敏注解

首先需要知曉具體是哪個(gè)類中的哪些屬性需要進(jìn)行脫敏處理,因此,需要自定義注解來實(shí)現(xiàn)對(duì)需要脫敏的屬性進(jìn)行標(biāo)注。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Desensitization {
    StrategyEnum strategy();
}

3.2 脫敏策略

有了標(biāo)注后,對(duì)于脫敏也會(huì)涉及到脫敏策略的問題。不同的屬性,應(yīng)該對(duì)應(yīng)不同的脫敏方式,例如,名字只保留姓氏,而身份證和電話號(hào)碼,則需要對(duì)中間的數(shù)字打碼。因此,在使用自定義注解進(jìn)行標(biāo)注的同時(shí),也要指定這個(gè)屬性對(duì)應(yīng)的脫敏策略,這里使用枚舉類枚舉出不同屬性對(duì)應(yīng)的正則處理。

import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor
public enum StrategyEnum {

    NAME(s -> s.replaceAll("([\\u4e00-\\u9fa5]{1})(.*)", "$1*")),
    ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2")),
    PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),
    ADDRESS(s -> s.replaceAll("(\\s{8})\\s{4}(\\s*)\\s{4})", "$1****$2****"));

    private final Desensitizer desensitizer;

}

3.3 脫敏執(zhí)行者

對(duì)于脫敏處理還需要一個(gè)執(zhí)行者,將屬性值和正則表達(dá)式進(jìn)行匹配和替換,進(jìn)而完成脫敏處理。這里我們利用了JDK8提供的一個(gè)非常好用的接口Fuction,它提供了apply方法,這個(gè)方法作用是為了實(shí)現(xiàn)函數(shù)映射,也就是將一個(gè)值轉(zhuǎn)換為另一個(gè)值。如果不了解的同學(xué)可以百度下 Fuction 接口。

import java.util.function.Function;

public interface Desensitizer extends Function<String, String> {
}

3.4 自定義數(shù)據(jù)脫敏攔截器

因?yàn)橐獙?duì)結(jié)果集進(jìn)行脫敏處理,所以要攔截的對(duì)象肯定是ResultSetHandler,并且是第一個(gè)方法。(可以想一下為啥是第一個(gè)方法)

public interface ResultSetHandler {
    <E> List<E> handleResultSets(Statement var1) throws SQLException;

    <E> Cursor<E> handleCursorResultSets(Statement var1) throws SQLException;

    void handleOutputParameters(CallableStatement var1) throws SQLException;
}

來看下具體的實(shí)現(xiàn):

import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.sql.Statement;
import java.util.List;
import java.util.stream.Stream;

@Component
@Intercepts(@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = Statement.class))
public class DesensitizationPlugin implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 獲取結(jié)果集
        List<Object> records = (List<Object>) invocation.proceed();
        // 處理結(jié)果集
        records.forEach(this::desensitization);
        return records;
    }

    /**
     * 2 * 判斷哪些需要脫敏處理
     * 3 * @param source 脫敏之前的源對(duì)象
     * 4
     */
    private void desensitization(Object source) {
        // 反射獲取類型中的所有屬性,判斷哪個(gè)需要進(jìn)行脫敏
        Class<?> sourceClass = source.getClass();
        MetaObject metaObject = SystemMetaObject.forObject(source);
        Stream.of(sourceClass.getDeclaredFields())
                .filter(field -> field.isAnnotationPresent(Desensitization.class))
                .forEach(field -> doDesensitization(metaObject, field));
    }

    /**
     * 2 * 真正的脫敏處理
     * 3 * @param metaObject
     * 4
     */
    private void doDesensitization(MetaObject metaObject, Field field) {
        String name = field.getName();
        Object value = metaObject.getValue(name);
        if (value != null && metaObject.getGetterType(name) == String.class) {
            Desensitization annotation = field.getAnnotation(Desensitization.class);
            StrategyEnum strategy = annotation.strategy();
            String apply = strategy.getDesensitizer().apply((String) value);
            metaObject.setValue(name, apply);
        }
    }
}

數(shù)據(jù)脫敏字段:

import com.example.cl.mybatisPlugin.Desensitization;
import com.example.cl.mybatisPlugin.StrategyEnum;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class User {
    private Long id;
    @Desensitization(strategy = StrategyEnum.NAME)
    private String name;
    private Integer age;
}

最后看下脫敏結(jié)果:

圖片圖片

4. 總結(jié)

根據(jù)上面的說明,我們來看看MyBatis 攔截器的優(yōu)勢(shì)和不足

  • 優(yōu)勢(shì):

非侵入式:通過攔截器機(jī)制,不需要修改 MyBatis 源碼即可定制功能。

靈活性:可以在多個(gè)階段對(duì) SQL 操作進(jìn)行干預(yù),從而實(shí)現(xiàn)豐富的功能。

  • 不足:

性能開銷:如果攔截器過多或者邏輯復(fù)雜,可能會(huì)導(dǎo)致性能下降。

調(diào)試?yán)щy:攔截器的執(zhí)行過程較為隱式,調(diào)試時(shí)可能會(huì)遇到一定的困難。

因此,我們攔截器不能創(chuàng)建過多,如果攔截的對(duì)象同一個(gè),那么我們可以將多個(gè)功能放到同一個(gè)攔截器當(dāng)中,從而減少攔截器的創(chuàng)建。

責(zé)任編輯:武曉燕 來源: Java極客技術(shù)
相關(guān)推薦

2025-01-02 10:10:51

2023-11-13 08:16:08

MySQL數(shù)據(jù)數(shù)據(jù)庫

2019-07-09 08:23:07

數(shù)據(jù)安全旅游網(wǎng)絡(luò)安全

2024-09-09 16:50:21

2024-08-29 08:58:30

JPA編寫數(shù)據(jù)操

2024-07-17 08:29:20

2016-04-29 10:02:39

2025-03-11 08:34:22

2009-06-24 16:00:00

2016-09-09 01:07:06

數(shù)據(jù)中心容量規(guī)劃數(shù)據(jù)中心

2009-09-27 17:37:32

Hibernate攔截

2025-02-28 08:14:53

2024-02-28 09:35:52

2019-12-19 08:56:21

MybatisSQL執(zhí)行器

2023-09-05 08:58:07

2025-06-09 07:35:00

NumPy數(shù)據(jù)分析數(shù)組

2011-05-16 10:14:11

Hibernate

2022-03-24 09:13:54

Mybatis加密解密

2009-07-08 17:02:11

JDK實(shí)現(xiàn)調(diào)用攔截器

2011-11-21 14:21:26

SpringMVCJava框架
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 91在线视频国产 | 午夜免费在线观看 | 麻豆精品一区二区三区在线观看 | 伊人欧美视频 | 中文字幕丁香5月 | 亚洲一区二区在线播放 | 日日噜噜噜夜夜爽爽狠狠视频, | 一级黄色绿像片 | 亚洲永久字幕 | 日韩精品久久一区 | 成人不卡 | 性做久久久久久免费观看欧美 | 国产精品1区 | www.99热这里只有精品 | av网站免费观看 | 精品国产一区二区 | 美国a级毛片免费视频 | 黄色免费网站在线看 | 日韩欧美三级电影 | 精品一二区 | 免费精品 | 午夜三级网站 | 在线观看一区 | 一级黄色影片在线观看 | 黄色片大全在线观看 | 超碰8| 中文字幕亚洲一区二区三区 | 日韩福利| 美国一级黄色片 | 国产一级免费在线观看 | 午夜99| 颜色网站在线观看 | 麻豆一区二区三区 | www.操.com | 亚洲国产精品久久久久 | 欧美国产精品一区二区三区 | 在线欧美一区 | 色香蕉在线 | 国产精品久久久久久久久久免费看 | 五月天婷婷综合 | 99国产精品久久久久久久 |