有没有遇到过Mybatisplus插件失效?

news2024/9/25 15:01:30

背景

相信mybatisplus应该很多人都用过,当然有些人在项目中使用的是tk.mybatis,那么今天说到这个话题原理都是一样,首先mybatisplus会有很多插件,这些插件都会形成一个拦截器链路,具体可以学习下原理,这个地方就不过多叙说了,毕竟不是本篇博文的重点,那言归正传,比如哪些插件呢,分页插件必要的,其次mybatis动态修改SQL的语句,各种插件都需要添加到这个拦截链路中也就是plus中

mybatis失效的案例分享

在这里插入图片描述
这个是我定义的一个mybatis一个插件,结果是当我执行一个查询的时候并没有进行拦截
那这个问题涉及到mybatis这个插件的底层原理以及spring bean创建过程,还有spring的bean创建顺序的原理
首先我们这个项目用的是springboot+mybatis plus,为了让其实现一个分页的效果,肯定需要添加一个分页插件

@Configuration
@ConditionalOnClass(MybatisPlusInterceptor.class)
public class PagePluginConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

在这里插入图片描述

这样就可以实现分页的效果了 除此之外我还配置了一个自定义的一个mybatis插件

在这里插入图片描述

比如实现读写分离、一些日志操作、一些对SQL动态修改的功能,但是这个时候我这个自定义的插件没有生效?
那接下来我们一步步来分析下为什么
那么第一步,我们先确认下我们这个自定义插件有没有被spring识别到并且创建bean,但是从代码上看确实加了这个@component这个注解 所以会被扫描到
在这里插入图片描述

打了个断点,可以看到第一个就是我们的自定义插件,第二个就是分页插件

其实答案很明显了那就是插件执行的顺序问题了,我们都知道拦截链都是一个圆环,先加入到这个拦截器链的就是最后一个执行的,也就是说在这个地方是分页插件先执行,但是先执行就为什么无法执行后面的插件呢,其实分页插件就是mybatis插件中最后一个执行的,为什么这样说呢,看下源码
分页插件并没有执行invocation.proceed();这个方法,这方法是执行目标方法的,如果不调用这个插件也不会触发下一个插件
invocation.proceed() 方法在 MyBatis 的插件机制中扮演着至关重要的角色。它是一个类似于 Java 动态代理中的 InvocationHandler.invoke() 方法的作用,用于触发拦截器链中的下一个拦截器,或者是最终的目标方法(如果没有其他拦截器了)。
当你在 intercept 方法中调用 invocation.proceed() 时,会继续执行拦截器链中的下一个拦截器,或者如果当前是最后一个拦截器,则会执行目标对象的实际方法。如果某个插件执行完之后没有调用 invocation.proceed(),则不会继续执行后续的拦截器,也不会执行目标方法。这会导致整个调用链路中断,从而可能导致应用程序错误或异常。
具体来说:
1、不调用 invocation.proceed() 的影响:
如果你不调用 invocation.proceed(),那么当前插件之后的所有拦截器都不会被触发。
目标方法也不会被执行,这可能会导致应用程序无法正常完成预期的操作,例如数据库查询或更新不会发生。
应用程序可能会因为缺少必要的处理步骤而失败。
2、调用 invocation.proceed() 的意义:
调用 invocation.proceed() 可以使拦截器链中的下一个插件有机会执行其逻辑。
如果当前插件是最后一个拦截器,那么调用 invocation.proceed() 会使目标方法被执行。

示例
以下是一个简单的示例,展示了如何在 intercept 方法中使用 invocation.proceed():

public class CustomPlugin implements Interceptor {

  @Override
  public Object intercept(Invocation invocation) throws Throwable {
    System.out.println("Before method call");
    Object result = invocation.proceed(); // 继续执行下一个插件或目标方法
    System.out.println("After method call");
    return result;
  }

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

  @Override
  public void setProperties(Properties properties) {
    // 设置插件属性
  }
}

在这个例子中,intercept 方法会在执行目标方法之前和之后打印消息。通过调用 invocation.proceed(),确保了目标方法能够被执行。
总结来说,invocation.proceed() 是用来继续执行拦截器链中的下一步骤的关键方法。如果不调用它,将会阻止进一步的执行,从而可能导致应用程序逻辑上的问题。因此,在编写 MyBatis 插件时,一定要注意正确调用 invocation.proceed()。

那分页插件为什么最后没有调用这个方法呢

在 MyBatis 的分页插件设计中,通常会在 intercept 方法中对 SQL 语句进行修改,而不是直接调用 invocation.proceed()。这是因为分页插件的主要目的是修改 SQL 语句,使其包含分页逻辑(例如添加 LIMIT 和 OFFSET 子句),而不是简单地继续执行原生的 SQL 语句。

分页插件的工作原理通常是这样的:

  1. 拦截 SQL 语句

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2163884.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

普渡大学和麻省理工学院合作开发集成视触觉指尖传感器的5自由度抓手

虽然机器人已经开始在现代制造业、医疗、服务业等领域进行渗透,但对于机器人尤其是机械臂的操作能力,仍然有很大的提升空间,传统多指机器人手虽然能够实现复杂的操作任务,但其高度冗余性也带来了不必要的复杂性。近日来自普渡大学…

WebRTC中的维纳滤波器实现详解:基于决策导向的SNR估计

目录 1. 维纳滤波器的基本原理2. WebRTC中的维纳滤波器实现3. 代码逐步剖析4. 总结 在WebRTC的噪声抑制模块中,维纳滤波器(Wiener Filter)是一种非常常见且重要的滤波器,用于提高语音信号的清晰度并抑制背景噪声。本文将详细解释维…

Hugging Face Transformer:从原理到实战的全面指南

一、前言 我们知道ChatGPT和所有预训练大语言模型的核心是什么?其实就是 Transformer,Hugging Face 的火爆离不开他们开源的这个 Transformers 库。这个开源库里有数万个我们可以直接调用的模型。很多场景下,这个开源模型已经足够我们使用了。…

【Pyside】pycharm2024配置conda虚拟环境

知识拓展 Pycharm 是一个由 JetBrains 开发的集成开发环境(IDE),它主要用于 Python 编程语言的开发。Pycharm 提供了代码编辑、调试、版本控制、测试等多种功能,以提高 Python 开发者的效率。 Pycharm 与 Python 的关系 Pycharm 是…

2024年9月24日---关于MyBatis框架(3)

五 Mybatis的缓存 5.1 Mybatis缓存简介 缓存(cache):提前把数据存放到缓存当中,下一次再使用的时候,直接从缓存中拿,而不用再次去数据库中查询一次了。这样的优势在于:通过减少IO的⽅式,来提⾼程序的执⾏…

28岁打算转行靠谱么,这个年龄转行,有什么适合的行业么?

前言 大家好,我是职场小油条播妞,最近被一组表情包洗脑了。 (强哥表情包我就不放了,大家自行脑补) 我要让老板知道,招我进来,就要承担一定的风险 既然领导把岗位交给咱,证明这岗位…

short-link笔记

1.Accessors(chain true) (见于Result类的注解) 不写默认为false,当该值为 true 时,对应字段的 setter 方法调用后,会返回当前对象。 -->可用于链式编程 参:Accessors 注解详解-CSDN博客 2.关键信息脱敏 利用将class通过jackon序列化为…

Azure Data Box 80 TB 现已在中国区正式发布

我们非常高兴地宣布,Azure Data Box 80 TB SKU现已在 Azure 中国区正式发布。Azure Data Box 是 Azure 的离线数据传输解决方案,允许您以快速、经济且可靠的方式将 PB 级数据从 Azure 存储中导入或导出。通过硬件传输设备可加速数据的安全传输&#xff0…

Mybtais高级结果映射-多对一表映射

前言 从前我们只进行单表的sql操作,但是如果涉及多张表的操作,原先的映射关系就不太适用了,因此这里将会介绍Mybatis的高级结果映射技巧 准备工作 准备两张数据库表,一个员工表,一个部门表(我们使用oracle的…

彻底理解前端模块化

目录 引入历史问题 CommonJSexports导出module.exports导出require导入加载过程缺点 AMD规范(基本不用)require.js使⽤ CMD规范(基本不用)SeaJS的使⽤ ES Module简单使用export关键字import关键字export和import结合default⽤法im…

自然语言处理在人工智能领域的发展历程,以及NLP重点模型介绍

大家好,我是微学AI,今天给大家介绍一下自然语言处理在人工智能领域的发展历程,以及NLP重点模型介绍。本文详细介绍了自然语言处理的发展历程,同时深入探讨了各种自然语言处理模型的原理与应用。文章首先回顾了自然语言处理技术的发…

读论文《OmniGen: Unified Image Generation》

OmniGen演示了在单一框架内执行各种图像生成任务的能力。此外,它还具有推理能力和语境学习能力。 论文地址:2409.11340v1 (arxiv.org) 项目地址:GitHub - VectorSpaceLab/OmniGen 项目目前还不完整,论文展现的通用性十分强大&am…

【Java】Java中接口与内部类详解

目录 引言 一、接口(Interface) 1.1 接口的定义 1.1.1 接口的特点 1.2 接口的实现 1.3 接口的继承 1.4 接口的注意事项 1.5 代码示例 二、内部类(Inner Class) 2.1 内部类特点 2.2 成员内部类 2.2.1 对象的创建 2.…

基于SpringBoot社区疫情信息管理系统的设计和实现

文未可获取一份本项目的java源码和数据库参考。 选题的意义 保护好人民群众的基本安全,贯彻党的领导下中国一盘棋的基本准则。将病毒隔绝在外,信息系统的存在显得至关重要,应对新型冠状病毒肺炎疫情治理的实践背景。实时关注更新疫情动态&a…

开放式耳机哪个牌子的质量好?2024开放式蓝牙耳机排行榜前5强推荐!

​开放式耳机因其舒适的佩戴感和较小的耳朵损伤而广受好评。曾经让人头疼的漏音问题,随着科技的进步,已经有了显著改善,不再是个大问题。在拥挤的环境中,耳机音量过大不仅会打扰他人,也会让自己感到不适。因此&#xf…

双十一买什么?高性价比数码好物来袭,不心动都难!

​每年的双十一都是一场购物的狂欢盛宴,众多数码好物纷纷推出诱人的折扣。在这琳琅满目的数码产品中,电容笔无疑是一颗格外耀眼的 “星”。无论是学生党用于记录课堂笔记、撰写论文,还是绘画爱好者进行艺术创作、灵感挥洒,电容笔都…

linux -L16-linux 查看应用占用的资源top

linux 查看应用占用的资源top Targetsteps启动 top 命令排序进程:查看特定进程:过滤进程其他常用选项交互式帮助 Target linux 查看应用占用的资源top steps 在 Linux 系统中,top 命令是一个非常有用的工具,它提供了一个实时更…

springframework Ordered接口学习

Ordered接口介绍 完整路径: org.springframework.core.Ordered Ordered 接口是 Spring 框架中的一个核心接口,用于定义对象的顺序。这个接口通常用于需要排序的组件,例如 Spring 中的 Bean、过滤器(Filters)、拦截器…

SUSCTF2024-Redroid-出题笔记与解题思路

SUSCTF2024-Redroid-出题笔记与解题思路 Step1Step2Step3Step4 描述:题目要求使用安卓13/14系统真机 Step1 Java层的逻辑比较简单,两个Activity MainActivity读并验证password,正确即进入CheckActivity,同时会传递password pass…

铝壳电阻与普通电阻有什么区别?

铝壳电阻和普通电阻是电子元件中常见的两种电阻类型,它们在结构和性能上有一定的区别。铝壳电阻是具有金属外壳的电阻器,其外壳通常由铝合金制成,具有良好的散热性能。而普通电阻则没有金属外壳,只有一层绝缘材料包裹着电阻丝。 …