mybatis-plus如何编写一个插件呢?

在 MyBatis-Plus 中编写插件,本质上是实现 MyBatis 的 Interceptor 接口来拦截 SQL 执行过程。但更推荐的做法是开发 InnerInterceptor,它可以被统一注册到 MybatisPlusInterceptor 中,与分页、乐观锁等官方插件协同工作。

1. 编写插件类

实现 InnerInterceptor 接口,重写 beforeQuery 或 beforePrepare 等方法。这里我们选择在查询前记录时间,查询后计算耗时。

import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

public class SqlLogInnerInterceptor implements InnerInterceptor {

    // ThreadLocal 用于在同一个线程中保存开始时间
    private static final ThreadLocal<Long> START_TIME = new ThreadLocal<>();

    @Override
    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter,
                            RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
        // SQL 执行前:记录开始时间
        START_TIME.set(System.currentTimeMillis());
        System.out.println("[SQL-Log] 准备执行: " + boundSql.getSql());
    }

    @Override
    public void afterQuery(Executor executor, MappedStatement ms, Object parameter,
                           RowBounds rowBounds, ResultHandler resultHandler,
                           BoundSql boundSql, Object result) {
        // SQL 执行后:计算并打印耗时
        Long start = START_TIME.get();
        if (start != null) {
            long cost = System.currentTimeMillis() - start;
            System.out.println("[SQL-Log] 执行完毕,耗时: " + cost + " ms");
            START_TIME.remove(); // 防止内存泄漏
        }
    }
}

2. 注册插件

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        
        // 1. 添加自定义的日志插件
        interceptor.addInnerInterceptor(new SqlLogInnerInterceptor());
        
        // 2. 如果原来就有分页插件,保留它(建议放在自定义插件之后)
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        
        return interceptor;
    }
}

注意事项:

  • 如果多个插件拦截同一个方法,执行顺序取决于 addInnerInterceptor 的添加顺序。
  • 插件中使用的 ThreadLocal 务必在 after 方法中 remove(),防止线程池复用导致内存泄漏或数据错乱。
  • 如果只是简单记录日志,用 AOP 切面可能更轻量;但如果需要对 SQL 本身做修改(如动态改表名、加条件),插件是唯一的选择。
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇