解决SpringBoot整合MybatisPlus分模块管理遇到的bug

前言

这个Bug前前后后折腾了两天才找到答案,虽说不是完全两天的工作时间在调试这个问题,但是过程也确实曲折,所以做一下记录,也当做一次自我反省

背景

SpringBoot 与 MyBatis-Plus 的 pom 依赖

<!-- SpringBoot 版本 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- MyBatis-plus 版本 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.1.0</version>
</dependency>

项目分模块结构

之前一直停留在 SpringBoot 整合其他框架做一些小项目,所以都是把代码放在一个工程,也没有进行分模块管理。

由于公司打算开发新产品,我想尝试在 SpringBoot 的项目来做分模块的开发(Maven工程),并且用 MyBatis-Plus 来做持久层框架,也就是将 SpringBoot 做 web模块, 实体跟Mapper 拆分到 persistence模块,并将 mapper.xml 文件放在 persistence模块 的 resources/mapper 目录下。

在项目分模块完成之后,并进行代码移植时并没有发现问题,因为此时并不需要调用到自定义 mapper.xml 中的 sql 查询数据库。但随着一步一步的完善代码,也开始需要用到 mapper.xml 的 sql 查询,此时,在调试时,发现了如下错误:

即,报找不到对应的 sql

排查原因

排除 mapper.xml 书写错误

首先排除 mapper.xml 中 namespace 或 sql 的 id 写错,因为我的开发工具下载了 MybatisX 的插件,mapper.java 与 mapper.xml 都有插件的小图标,如下图所示,

怀疑:分模块导致

其次,在先前我已经整合过 SpringBoot 与 MyBatis-Plus 单项目的工程,并没有这个问题,所以,我怀疑是因为 分模块导致的原因 导致的,所以,我想 分模块跟不分模块的工程 有区别?

区别就是,不分模块 mapper.xml 文件就在项目 classes 下的 mapper 中,而分模块后, mapper.xml 文件就在 persistence模块打出来的 jar 中

错误思路:修改pom文件配置resources目录

所以,发现了这点之后,就开始必应解决方案,但是刚开始我的思路是 错误的,我以为项目打包之后,没有把 persistence模块的 resources 下 的 mapper 目录打包进 jar 中 。浪费了一些时间之后,我才想清楚应该先去 persistence模块 打出来的 jar 中确认有没有将 resources 下的 mapper/mapper.xml 打包进去。

怀疑:Spring Resource时没有加载 jar 中的 mapper.xml

上面的问题教了自己一课,眼见为实 ,虽然解决 Bug 的过程中,合理的猜测是必要的,但是在有限的结果集中,验证排除一些错误的思路更为重要。就像,经常有人会问我,“为什么我运行老是报找不到类的错误”,我就说那你到 tomcat 的发布路径上看一下 jar 包有没有发不上去,这其实是一个道理的。

回到问题,为什么Spring Resource时没有加载 jar 中的 mapper.xml ?必应寻找解决方案,在必应的过程中我才想起了 Spring 的 Resource 加载文件, classpath 与 classpath* 的区别,好久没有自己手写搭项目,把这个给忘记了。

所以,此时我确信将 application.xml 中 mybatis-plus.mapper-locations 的值改为 classpath*:mapper/*Mapper.xml 即可,如下

#mapper plus
mybatis-plus:
  mapper-locations: classpath*:mapper/*Mapper.xml

怀疑:SpringBoot 跟 MyBatis-Plus 整合的配置哪里不对吗?

上面的配置修改之后,重新运行,还是报同样的错!!!

What The Fuck!!!因为我觉得这个 bug 就是由于 classpath:mapper/*Mapper.xml Spring 的 Resource 只能扫描当前应用中的 classpath 下的 mapper 目录的 mapper.xml 的文件,所以,我又重新必应了 SpringBoot 与 Mybati-plus 的整合配置 ,说到底还是对这个框架不了解,导致走了不少弯路,而且在出问题的时候,没有坚信自己的判断,而不断的尝试必应出来的结果,使得又浪费了一些时间在这个问题上。

最后必应了一圈后,还是没有找到解决方案,而且与此相关的问题文章也不多, 我开始迷茫跟急躁了,毕竟已经浪费了这么多的时间,我还是决定先验证一下我前面深信的东西---- Spring 的 Resource 加载文件, classpath 与 classpath* 的区别 ,所以,我决定自己创建 sqlSessionFactory ,代码如下

@Bean("sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory() throws Exception {
    MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
    sqlSessionFactory.setDataSource(datasource);
    ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
    Resource[] resources = resolver.getResources("classpath*:mapper/*Mapper.xml");
    sqlSessionFactory.setMapperLocations(resources);
    MybatisConfiguration configuration = new MybatisConfiguration();
    configuration.setJdbcTypeForNull(JdbcType.NULL);
    configuration.setMapUnderscoreToCamelCase(true);
    configuration.setCacheEnabled(false);
    sqlSessionFactory.setConfiguration(configuration);
    //添加分页功能
    sqlSessionFactory.setPlugins(new Interceptor[]{
        paginationInterceptor()
    });
    return sqlSessionFactory.getObject();
}

结果是运行通过了!!不过,这也是理所当然的,这就说明了我在 application.xml 中 mybatis-plus 的配置没生效,相当于又回到了上一个问题。到了这里,我才想到去看 mybatis-plus-boot-starter 里面的源码!!

没想到的是,源码相当容易看,首先,jar 包的目录结构如下,看名字直接选择看 MybatisPlusAutoConfiguration 这个配置类

打开 MybatisPlusAutoConfiguration 的源码,直接看 SqlSessionFactory 的创建,如下,在设置 mapper-locations 的判断处,打下断点,进行调试

并且将前面自定义创建的 SqlSessionFactory 的代码注释掉,application.yml 中配置 mapper-locations: classpath*:mapper/*Mapper.xml ,重新运行,进行源码调试,发现上图断点的逻辑,没有进到 if 的判断中去,调试的 MybatisPlusProperties 对象结果如下,

!!!What The Fuck!!!我配置的明明是 classpath*:mapper/*Mapper.xml ,怎么变成了 classpath:mapper/*Mapper.xml 可恨的是,我的思路有绕弯了!!!

怀疑:yml 的配置语法对 classpath*:mapper/*Mapper.xml 解析有问题

我都服了我自己了,但确实是这次修改让我找到了最后的答案,将原本的配置写法改成了数组,写法如下,

#mapper plus
mybatis-plus:
  mapper-locations: [classpath*:mapper/*Mapper.xml]

因为对这种配置格式也没去深究,之前都是一对一的配置项,没有尝试过数组的写法,所以上来就运行报错了,但是报的是 application.yml 的语法格式有误。所以,将值加上引号括起来,变成

#mapper plus
mybatis-plus:
  mapper-locations: ["classpath*:mapper/*Mapper.xml"]

重新运行,发现竟然通过了!!!源码调试的 mapperLocations 的值也是 classpath*:mapper/*Mapper.xml ,此时我以为找到了问题的所在了,就是 yml 的配置语法对 classpath*:mapper/*Mapper.xml 解析有问题 我也对此深信不疑。

结论:开发工具没有同步配置

在没写这笔记前,我还深信问题就是 yml 的语法对值带有 冒号 的解析时,需要对值用 引号 包起来。但是在写笔记做记录的过程中,需要还原场景,在调试的时候,发现并没有说 需要对带有冒号的值加上引号包起来 ,这时我才想起来,会不会是 开发工具的问题,在运行的时候,没有把修改的配置文件同步上去 。经过多次的调试,也证明了这点,有时候项目跑太久,开发工具就会突然出来发难。

搞了半天, 在 application.yml 的配置 classpath*:mapper/*Mapper.xml 是有效的!!!有效的!!!有效的!!! 相当于开发工具的作祟让我白白浪费了2天时间,但是期间也发现了自身的一下问题,太久没有遇到错误,一味的相信搜索引擎而不去思考,最后还差点 用错误的认识,否定了原本正确的东西 。

#mapper plus
mybatis-plus:
  mapper-locations: classpath*:mapper/*Mapper.xml

在发现 application.yml配置修改后没生效的第一时间,我就应该检查发布路径的文件,或者去调试源码。中间浪费太多的时间陷入盲目的必应搜索答案,做笔记反省一下自己,安定就会退步,坚持学习,永远不要放弃思考。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • springboot集成mybatis-plus遇到的问题及解决方法

    在使用spring boot集成mybatis-plus的过程中遇到的问题 如图, 首先我放xml的包的是没问题的,而是引入的架包和配置问题,问题配置如下 解决方法:请将mybatis-plus改成mybatis,mybatis,mybtis,重要的说三遍,必要的架包如下 <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring- boot-start

  • springboot整合mybatis中的问题及出现的一些问题小结

    1.springboot整合mybatis mapper注入时显示could not autowire,如果强行写(value  = false ),可能会报NullPointException异常 解决方案: dao层加注解@Component(value = "首字母小写的接口名如UserMapper->userMapper") dao层还可以加注解@Mapper 2.The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecogni

  • Mybatis整合Spring 由于版本引起的BUG问题

    错误信息: org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [SpringMVC] in context with path [/tech] threw exception [Handler dispatch failed; nested exception is java.lang.AbstractMethodError: org.mybatis.spring.transact

  • SpringBoot项目中遇到的BUG问题及解决方法

    1.启动项目的时候报错 1.Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled. 解决方法: 在yml配置文件中加入debug: true,因为默认的话是false 2.在集成mybatis时mapper包中的类没被扫描 org.springframework.beans.factory.NoSuchBean

  • 解决SpringBoot整合MybatisPlus分模块管理遇到的bug

    前言 这个Bug前前后后折腾了两天才找到答案,虽说不是完全两天的工作时间在调试这个问题,但是过程也确实曲折,所以做一下记录,也当做一次自我反省 背景 SpringBoot 与 MyBatis-Plus 的 pom 依赖 <!-- SpringBoot 版本 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent&

  • SpringBoot整合MyBatis-Plus乐观锁不生效的问题及解决方法

    目录 SpringBoot整合Myabtis-Plus 1.依赖导入 2.数据库插入 3.SpringBoot各个层次的操作 3.1.实体类 3.2.configuration 3.2.1.TableField的insert与update 3.2.2.乐观锁配置 3.3.mapper层 3.4.service层 4.控制层测试 4.1.查询所有 4.2.根据id修改信息 SpringBoot整合Myabtis-Plus 在与官网配置一致的情况下依旧无法生效,如下整合mybatis-plus 1.

  • SpringBoot整合Mybatis-Plus分页失效的解决

    场景:项目整合mybatis-Plus分页失效,current一直是1,size一直是10,total属性一直是0,数据分页不准 先看官网给的示例: 解决方案是新建mybatis-Plus的配置文件: package com.amc.config; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer; imp

  • SpringBoot整合MyBatisPlus配置动态数据源的方法

    MybatisPlus特性 •无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑 •损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作 •强大的 CRUD 操作:内置通用 Mapper.通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求 •支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错 •支持多种数据库:支持 MySQL.MariaDB.Ora

  • SpringBoot整合MyBatis-Plus的示例代码

    目录 前言 源码 环境 开发工具 SQL脚本 正文 单工程 POM文件(注意) application.properties(注意) 自定义配置(注意) 实体类(注意) Mapper接口(注意) Service服务实现类(注意) Controller前端控制器(注意) SpringBoot启动类(注意) 启用项目,调用接口(注意) 多工程 commons工程-POM文件 MyBatis-Plus commons工程-system.properties commons工程- 自定义配置 commo

  • springboot整合mybatis-plus逆向工程的实现

    MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发.提高效率而生.官方文档 代码生成器 AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity.Mapper.Mapper XML.Service.Controller 等各个模块的代码,极大的提升了开发效率. mybatis-plus是根据数据库表来生成对应的实体类,首先我们创建数据库表Us

  • springboot整合mybatis-plus代码生成器的配置解析

    AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity.Mapper.Mapper XML.Service.Controller 等各个模块的代码,极大的提升了开发效率. 具体实实现以及配置解析如下: package mybatis_plus; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.annot

  • SpringBoot整合mybatis-plus进阶详细教程

    目录 前言 wapper介绍 : 条件构造器 AbstractWrapper 一.什么是AbstractWrapper 二.QueryWrapper(LambdaQueryWrapper) 1.QueryWrapper用法示例 2.LambdaQueryWrapper用法示例 三.UpdateWrapper(LambdaUpdateWrapper) 1.UpdateWrapper用法示例 2.LambdaUpdateWrapper用法示例 mybatis-plus的插件 一.分页插件 1.配置分

  • SpringBoot整合mybatis-plus快速入门超详细教程

    目录 前言 mybatis-plus 简介 mybatis-plus 优点 相关链接 mybatis-plus实例 1.示例项目结构 2.数据库准备 3.pom.xml: 4.application.yml 5.User.java 6.UserMapper.java 7.UserServiceImpl.java 8.测试类 mybatis-plus的crud: 1.insert操作: 2.select操作: 3.update操作: 4.delete操作: 总结 前言 mybatis-plus 简

  • SpringBoot整合Mybatis-plus的具体使用

    目录 一.mybatis-plus简介: 二.springboot整合mybatis-plus案例 一.mybatis-plus简介: Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发.提高效率而生.这是官方给的定义,关于mybatis-plus的更多介绍及特性,可以参考mybatis-plus官网.那么它是怎么增强的呢?其实就是它已经封装好了一些crud方法,我们不需要再写xml了,直接调用这些方法就行,就类似于J

随机推荐