首页 > 其他分享 >mybatis-plus加载多个module的mapper踩坑记录

mybatis-plus加载多个module的mapper踩坑记录

时间:2024-06-12 13:33:05浏览次数:23  
标签:xml mapper 方法 module plus mybatis 断点 我们

背景

 有一个多模块的项目,每个模块中都有自己的mapper.xml文件。但是在执行一次SQL查询中,mybatis却报出了下面的异常

 

排查过程

第一步,先检查mapper扫描是否正确

 

先找到这个方法的位置

 

可以看到包名是com.pinming.security.responsibility.mapper

 

检查SpringBoot启动类的注解

 

用通配符的方式匹配路径,可以看到这个写法没有任何问题

 

然后我又执行了别的mapper类的查询,发现除了第一个module下的两个mapper的自定义查询方法能够被成功映射,其他mapper的方法都会报出上述异常,可以断定确实是mybatis没有扫描到全部的mapper.xml

 

为了知道是哪里出了问题,我们直接开始debug源码,探究mybatis扫描mapper.xml的原理

 

根据报错的堆栈信息,我们定位到了报错的最终位置

 

代码为什么会进入到这里?

我们先来看这里的判断逻辑:ms == null,且方法上不带Flush这个注解,程序就会进行到我们报错的位置

首先思考,Flush这个注解是什么?不知道,也没用过,而且印象中mapper的方法不需要这个注解也能注册上去,所以问题一定出在ms == null的问题上

那么ms是什么?怎么来的?再往上看,它的类型是MappedStatement,逐词翻译就是“映射的语句”,通过resolveMappedStatement方法得到,那我们将断点加到这里,重新执行代码

 

进入方法内部

 

发现最后因为configuration.hasStatement(statementId) = falsemapperInterface.equals(declaringClass) = true,最后返回了null

后一个判断分支判断的时接口名称是否匹配,这里一定会匹配,前一个判断分支判断是否有这个语句,很显然没找到,那么继续debug进入前一个语句

 

 

这里我debug到buildAllStatements方法里看了半天,发现问题不在这里,就不赘述了

这里我们发现,所有语句被映射在了mappedStatements

 

找到它被赋值的地方,我们就能知道mapper中我们自定义的方法是在哪里被映射的

 

 

它有唯一的put入口,将断点加在这里,我们重启程序,观察映射的过程

 要注意这里要给断点加一个condition,ms.getId()就是方法的全路径,只看自己加的方法是怎么被映射的,因为mybatis-plus的baseMapper有很多内置的方法是通过其他方法初始化的,不要去管那些

 

我们根据这个堆栈列表,一点点往回看

此处省略几十分钟,中间走错了很多路。最终我们找到了这里

 

遍历mapperLocations,解析每一个xml,正常来说mapperLocations肯定会包含每个mapper.xml,那我们看看它有哪些值

 

居然只有meeting这个模块下的两个mapper.xml?为什么?

我们往上找一下这个mapperLocations是怎么来的

 

 

用同样的方法,找到了它唯一被赋值的地方,打下断点,重启程序。感觉离真相越来越近了哈哈哈!

 

进入断点,同样通过左下角的堆栈信息不断往回找

 

这回只往上找了一步就发现了加载它的地方

再把断点打在properties.resolveMapperLocations()这行,重启!

 

下面贴上我debug操作的每一步,红框就是我debug进入的方法体

 

 

 

 这里是什么?一脸懵逼,我先看看最后会进到哪个分支

 

再进去

 

这里看到,spring根据我们配置的mapper.xml路径,开始搜索所有匹配的文件

走到这里不用往下看了,因为这往下的搜索都是根据locationPattern这个入参来决定的,问题一定出在locationPattern

确定了之后,我们再往回一步

 

到这里,我们仔细阅读代码,发现一个关键的词语:all

通过猜测,我们得通过调整locationPattern的值,让代码进入上面的分支,继续往前看看locationPattern是怎么来的

 

在这里,遍历mapperLocations得到下面的入参locationPattern

 

这个mapperLocations是一个成员变量,并且我们发现MybatisPlusProperties这个类是通过配置文件注入的

 

在配置文件中搜索mybatis-plus

 

破案了!就是这个值!

那我们要改成什么值呢?回到前面的判断分支

 

 

可见,我们的配置必须以classpath*:开头

试一试

 

配置完之后重启,执行方法,成功!

结论

想要多个module中的mapper.xml文件都被加载到,配置文件中mybatis-plus.mapper-locations这一项必须以classpath*:开头,否则就只会加载匹配到的第一个module中的指定目录

 

标签:xml,mapper,方法,module,plus,mybatis,断点,我们
From: https://www.cnblogs.com/little-nobody/p/18243764

相关文章

  • 【Python】成功解决ModuleNotFoundError: No module named ‘PyQt5‘
    【Python】成功解决ModuleNotFoundError:Nomodulenamed‘PyQt5’ 下滑即可查看博客内容......
  • Java (MyBatis-Plus 项目)
    前沿MyBatis-Plus在使用这个时候的它通过提供简洁、强大的API和注解支持,简化了常见的数据库操作。以下是关于MyBatis-Plus中注解的解释和示例,理解和使用1.实体类注解@TableName:用于指定数据库表的名称。@TableId:用于指定主键字段。@TableField:用于指定非主键字段......
  • IC693CPU331S CPU 331 Module
    IC693CPU331S  CPU 331 Module板卡控制通常具有较高的实时性能,可以在短的响应时间内进行控制和监测。这是因为板卡控制直接与硬件设备连接,并通过硬件接口进行数据采集和输出控制。它不依赖于外部的通信和传输过程,因此可以实时地对设备进行控制和反馈。PLC控制的实时性能相......
  • 3G2A5-ID218 Input Module
    变频器电源变频器电源主要用于交流电机的变频调速,其在电气传动系统中占据的地位日趋重要,已获得巨大的节能效果。变频器电源主电路均采用交流-直流-交流方案。工频电源通过整流器变成固定的直流电压,然后由大功率晶体管或IGBT组成的PWM高频变换器, 将直流电压逆变成电压、频......
  • Springboot + Mybatis Plus整合Sqlite3
    什么是Sqlite3sqlite3是一个进程内的库,实现了自给自足、无服务器、零配置、事务性的SQL数据库引擎。它是一个增长最快的数据库引擎。它不是一个独立的进程,可以按应用程序需求进行静态或动态连接,SQLite直接访问其存储文件。为什么要使用Sqlite3不需要一个单独的服务器进程......
  • 【微服务】第3节:MybatisPlus的扩展功能
    目录1.扩展功能1.1.代码生成1.1.1.安装插件1.1.2.使用1.2.静态工具1.3.逻辑删除1.3.通用枚举1.3.1.定义枚举1.3.2.配置枚举处理器1.3.3.测试1.4.JSON类型处理器1.4.1.定义实体1.4.2.使用类型处理器1.5.配置加密(选学)1.5.1.生成秘钥1.5.2.修改配置1.5.3.测试......
  • springboot使用ComponentScan和MapperScan
    今天讲springboot项目中的启动类换到了start包下,发现无法扫描并注册javabean. 原因:容器在启动时会由spring.classPathBeanDefinitionScanner和spring-mybaits.classPathMapperScanner两个类去执行doScan方法,如果没有使用@ComponentScan和MapperScan两个注解spring会使用Spring......
  • C++Primer Plus 第12章 类和动态内存分配 12.10编程练习第2题new,delete的指向深度拷
    系列文章目录提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加例如:本章练习第2题涉及标准函数及关键词toupper,tolower(),strcpy_s(),strcat_s(),strcmp,strlen(),new[],delete[].实现如下效果输出应与下面相似:Pleaseenteryourname:FrettaFarboMynameis......
  • C++Primer Plus 第12章 类和动态内存分配 12.10编程练习第1题new,delete的指向深度拷
    C++PrimerPlus第12章类和动态内存分配12.10编程练习第1题`提示:练习一定要动手操作涉及标准函数及关键词1,new[],delete[],strlen(),strcpy_s(),cout,endl,explicit例如:1,对于下面的类的声明:`提示:设计数组和字符串的new,delete文章目录C++PrimerPlus第12章类......
  • MyBatisPlus总结二
    MybatisPlus总结一在这:MybatisPlus总结1/2-CSDN博客六、分页查询:6.1.介绍:        MybatisPlus内置了分页插件,所以我们只需要配置一个分页拦截器就可以了,由于不同的数据库的分页的方式不一样,例如mysql和oracle数据库的写法是完全不一样的,所以我们需要去指定一个数......