自测学习分享:MyBatis 迁移 MyBatis-Plus 及 XML 路径规范实践

13 阅读9分钟

一、分享背景与自测初衷

作为后端开发,在日常维护现有稳定项目的同时,也需提前布局技术储备,为将来可能的项目重构、技术升级做好准备。现有负责的后端项目以devservice设备中心为例,基于 MyBatis+PageHelper 技术栈稳定运行,XML 映射文件统一存放于src/main/java/mapper目录,虽能满足业务需求,但随着技术迭代,MyBatis-Plus 的高效开发能力、规范的资源管理模式,更适配未来项目重构的需求。

本次自测学习的核心初衷的是:通过自主自测、踩坑排查、实践验证,熟练掌握 MyBatis 平滑迁移 MyBatis-Plus 的全流程,规范 XML 资源路径管理,积累项目重构所需的技术经验,同时将自测过程中的问题、解决方案及心得分享出来,为团队后续同类技术实践提供参考,也为自身技术能力提升夯实基础

不同于正式项目优化,本次自测全程以 “学习实践、经验积累” 为核心,不改动现有业务代码、不影响项目稳定运行,重点聚焦 “技术适配、问题排查、经验沉淀”,为将来可能的项目重构,提前扫清技术障碍、储备可落地的实践经验。

二、MyBatis-Plus 核心优势(为何作为重构储备技术)

提前学习并实践 MyBatis-Plus,核心是看中其适配项目重构的诸多优势,也是未来项目升级的优选方向,其核心价值的体现在:

  1. 兼容可控:完全兼容原生 MyBatis 语法及现有 PageHelper 分页插件,若未来项目重构,可实现平滑迁移,无需大规模重构历史代码,降低重构风险;
  2. 高效提效:内置 BaseMapper 通用接口,封装了单表 CRUD 全部方法,可大幅减少重构后新增业务的重复 SQL 编写工作量,提升开发效率;
  3. 规范易维护:支持自定义 XML 扫描路径配置,可实现 XML 资源从src/main/java/mapper到resources/mapper的规范归置,适配 Maven 工程资源管理规范,降低重构后项目的维护成本;
  4. 可扩展性强:自带分页插件、条件构造器、逻辑删除等实用功能,可满足未来项目重构后,业务迭代的多样化需求,减少自定义工具类的开发成本。

基于以上优势,本次自测重点实践 MyBatis 迁移 MyBatis-Plus 的全流程,同步规范 XML 资源路径,为将来项目重构积累可落地的技术经验。

三、XML 映射文件存放于 src/main/java 目录的核心弊端

Maven 工程对目录结构有明确的职责划分:src/main/java专用于存放 Java 源代码,src/main/resources用于存放配置文件、XML、静态资源等非代码类资源。将 XML 映射文件放在src/main/java目录,违背这一规范的同时,还会带来一系列实际开发与维护问题,也是本次自测中重点验证并希望解决的痛点。

四、自测实践全流程(聚焦学习与经验积累)

本次自测严格遵循 “学习 - 实践 - 排查 - 总结” 的思路,全程自主操作、自主踩坑,不依赖外部支持,重点锻炼自身的问题排查能力和技术实践能力,具体实践步骤如下:

步骤 1:依赖梳理与 MyBatis-Plus 引入(基础实践)

首先梳理现有项目的依赖体系,明确原生 MyBatis 与其他插件的版本兼容关系,自主实践 “引入 MyBatis-Plus、清理冗余依赖” 的操作,为自测搭建基础环境,同时积累依赖适配经验:

<!-- 引入MyBatis-Plus核心包(重点实践兼容原生MyBatis) -->
<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.4.1</version>
</dependency>
 <dependency>
            <groupId>com.github.jsqlparser</groupId>
            <artifactId>jsqlparser</artifactId>
            <version>4.6</version>
</dependency>
<!-- 自主实践清理冗余依赖:移除原生MyBatis包,避免版本冲突(积累依赖冲突解决经验) -->
<!-- <dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
</dependency> -->
<!-- 保留现有PageHelper依赖,实践MyBatis-Plus与现有插件的兼容性 -->
<!-- <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-annotation</artifactId>
            <version>3.3.1</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-extension</artifactId>
            <version>3.3.1</version>
            <exclusions>
                <exclusion>
                    <groupId>com.github.jsqlparser</groupId>
                    <artifactId>jsqlparser</artifactId>
                </exclusion>
            </exclusions>
            <scope>compile</scope>
</dependency> -->

<!-- 保留现有PageHelper依赖,实践MyBatis-Plus与现有插件的兼容性 -->
<dependency>
          <groupId>com.github.pagehelper</groupId>
          <artifactId>pagehelper-spring-boot-starter</artifactId>
          <version>1.4.7</version>
</dependency>

此步骤重点学习:如何基于现有项目依赖,合理引入新工具,如何排查并清理冗余依赖,为未来项目重构时的依赖适配积累经验。

步骤 2:分页插件与配置优化(核心实践)

自主编写 MyBatis-Plus 分页拦截器配置,实践其与现有 PageHelper 分页插件的兼容性;同时优化配置文件,将 XML 扫描路径指定为resources/mapper,实践资源路径规范化配置,积累配置优化经验:

第一:先加入mybatis-plus拦截器

@Configuration
public class MyBatisPlusConfig {
    /**
     * 实践MyBatis-Plus分页插件配置,重点验证与现有PageHelper的兼容性
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        paginationInnerInterceptor.setOverflow(true); // 溢出页数处理,积累分页配置细节经验
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        return interceptor;
    }
}

本地bootstrap.properties 配置优化,重点实践规范路径配置:

mybatis-plus.mapper-locations=classpath*:mapper/*Mapper.xml
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
mybatis-plus.configuration.default-statement-timeout=30
mybatis-plus.configuration.cache-enabled=false

同时,自主清理远程配置中心冗余的 MyBatis 路径配置,学习 “避免配置冲突” 的方法,为未来项目重构时的配置管理积累经验。

步骤 3:自测用例开发(全链路实践)

为验证自测效果、巩固实践经验,自主开发极简分页查询自测用例,覆盖控制层、服务层、持久层全链路,不改动现有业务代码,重点实践 “MyBatis-Plus 功能使用、XML 路径扫描、远程配置加载” 的全流程,积累代码编写与全链路验证经验:

1. 控制层(实践远程配置加载与参数接收)

public class TestController {
    @Autowired
    private TestService testService;

    // 实践远程配置注解读取,学习配置加载验证的方法
    @Value("${myname}")
    private String myname;

    @PostMapping("t1")
    public APIResponse test(@RequestBody Query query) throws Exception {
        System.out.println(myname); // 验证远程配置加载,积累配置排查经验
        // 实践MyBatis-Plus分页功能调用,巩固全链路衔接技巧
        IPage<PowerStation> test = testService.test(query.getPageNum(),query.getPageSize());
        return ResponseHandle.getInstance().data2APIResponse(test);
    }
}

2. 服务层(实践 MyBatis-Plus BaseMapper 复用)

// 自测服务接口,规范接口定义格式
public interface TestService {
    IPage<PowerStation> test(Integer pageNum, Integer pageSize);
}
// 服务实现类,重点实践MyBatis-Plus ServiceImpl、BaseMapper的复用技巧
@Service
public class TestServiceImpl extends ServiceImpl<PowerStationMapper, PowerStation> implements TestService{
    @Override
    public IPage<PowerStation> test(Integer pageNum, Integer pageSize) {
        // 实践MyBatis-Plus Page分页对象的使用方法
        Page<PowerStation> page = new Page<>(pageNum,pageSize);
        // 实践规范路径下XML的调用,验证路径配置有效性
        IPage<PowerStation> pageList = baseMapper.selectListAll(page);
        return pageList;
    }
}

3. 持久层(实践规范路径 XML 编写)

在resources/mapper目录下新增测试用 XML 文件,自主编写分页查询 SQL,实践规范路径下 XML 的编写格式、namespace 配置,同时确保原有src/main/java/mapper目录下的 XML 正常使用,积累 “新旧路径共存” 的实践经验,为未来项目重构时分批迁移 XML 做好准备。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sungrow.sgframe.api.isolarapi.devservice.mapper.PowerStationMapper">

    <select id="selectListAll"
            resultType="com.sungrow.sgframe.api.isolarapi.devservice.pojo.entity.PowerStation">
        select * from power_station where RECORE_CREATE_TIME>='2025-12-04 10:59:10'

    </select>
    
</mapper>

四、自测踩坑与问题排查(核心经验积累)

本次自测的核心价值,不仅在于掌握了 MyBatis-Plus 的引入与配置,更在于通过自主踩坑、分层排查,积累了项目重构时可能遇到的问题及解决方案,这也是本次学习分享的重点。

1. 自测异常现象

完成上述实践配置后,项目启动正常,远程配置加载正常(控制台成功输出myname=zhangsan),但调用自测接口时,抛出Invalid bound statement (not found)异常 ——resources/mapper目录下的新增 XML 无法被扫描,而原有src/main/java/mapper目录下的 XML 可正常使用,与自测预期不符。

2. 分层排查过程(自主排查,积累经验)

面对异常,没有急于寻求帮助,而是自主按照 “从易到难、分层排查” 的思路,逐步定位问题根因,重点锻炼自身的问题排查能力,具体排查过程如下:

排查1:方法名配置是否正确

首先排查selectListAll方法是否正确,mybatis-plus.mapper-locations的路径是否正确,没问题

排查 2:XML 资源打包验证(基础排查)

首先怀疑 XML 未被 Maven 正常打包,执行mvn clean compile后,查看target/classes/mapper目录,确认新增测试 XML 已正常编译、内容完整,排除 “资源未打包” 的问题,同时积累 “资源打包排查” 的基础技巧。

排查 3:依赖版本兼容性验证(重点排查)

随后怀疑 MyBatis-Plus 与现有依赖冲突,通过mvn dependency:tree分析依赖树,自主排查版本兼容问题,发现jsqlparser依赖版本与 MyBatis-Plus 不适配,通过强制指定 4.6 版本,解决了潜在的类加载异常问题,积累 “依赖冲突排查与解决” 的核心经验。

排查 4:配置优先级验证(核心排查)

经过前两次排查,异常仍未解决,随后自主梳理项目中所有与 MyBatis 相关的配置,最终定位到项目中遗留的自定义数据源配置类MysqlDataSourceConfig—— 这是本次自测踩坑的核心根因。

该类手动创建SqlSessionFactory,并指定 XML 扫描路径为classpath*:com/sungrow/**/mapper/*.xml,仅覆盖src/main/java/mapper目录;而 MyBatis-Plus 自动装配的优先级低于手动配置,导致bootstrap.properties中指定的resources/mapper路径失效,新增 XML 无法被扫描。

@Configuration
@MapperScan(basePackages = "com.sungrow.sgframe.api.isolarapi.devservice.mapper", sqlSessionFactoryRef = "sqlSessionFactory")
public class MysqlDataSourceConfig {
    @Primary // 表示这个数据源是默认数据源, 这个注解必须要加,因为不加的话spring将分不清楚那个为主数据源(默认数据源)
    @Bean("dataSource")
    @ConfigurationProperties(prefix = "spring.datasource") //读取application.yml中的配置参数映射成为一个对象
    public DataSource dataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    /**
     * 用于配置文件中的mybatis.configuration域下的配置。由于自定义数据的原因,该配置不会被自动加载,所以会导致该域下的配置读取失败
     *
     * @return MyBatis Global configuration
     */
    @Bean("globalConfiguration")
    @ConfigurationProperties(prefix = "mybatis.configuration")
    public org.apache.ibatis.session.Configuration globalConfiguration() {
        return new org.apache.ibatis.session.Configuration();
    }

    @Primary
    @Bean("sqlSessionFactory")
    public SqlSessionFactory db1SqlSessionFactory(@Qualifier("dataSource") DataSource dataSource,
                                                  @Qualifier("globalConfiguration") org.apache.ibatis.session.Configuration configuration) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        // 手动加载mybatis.configuration的配置
        bean.setConfiguration(configuration);
        // mapper的xml形式文件位置必须要配置,不然将报错:no statement (这种错误也可能是mapper的xml中,namespace与项目的路径不一致导致)
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:com/sungrow/**/mapper/*.xml"));
        return bean.getObject();
    }

    @Primary
    @Bean("sqlSessionTemplate")
    public SqlSessionTemplate db1SqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory){
        return new SqlSessionTemplate(sqlSessionFactory);
    }

}

将这块配置删除不需要,mybatis-plus默认会自动创建sqlSessionFactory(删除后会有$()报错,可单独在加配置)

通过这次排查,深刻掌握了 “自定义配置与框架自动装配优先级” 的核心知识点,也积累了 “配置冲突排查” 的关键经验 —— 这也是未来项目重构时,极有可能遇到的问题。

3. 解决方案(实践配,积累经验)

为确保自测继续推进,同时保留原有配置备份(模拟项目重构时的 “保留历史配置” 场景),自主决定注释自定义数据源配置类MysqlDataSourceConfig,依托 MyBatis-Plus 自动装配能力,加载数据源及 XML 扫描配置,最终解决了 XML 扫描失败的问题。

同时,也总结出两种解决方案(适配未来项目重构的不同场景),积累了灵活适配的实践经验:

  1. 方案 1:注释 / 删除冗余自定义配置,依托框架自动装配(适合重构时 “清理冗余配置” 的场景);
  2. 方案 2:修改自定义配置的 XML 扫描路径,新增resources/mapper路径,实现新旧路径共存(适合重构时 “分批迁移 XML” 的场景)。

五、自测成果与经验沉淀(核心分享内容)

1. 自测实践成果

经过自主实践、踩坑排查,本次自测最终达成预期目标,各项验证均符合要求:

  1. 功能验证成功:MyBatis-Plus 成功引入,与现有 MyBatis+PageHelper 完全兼容,分页功能正常运行;
  2. 路径规范成功:resources/mapper目录可作为 XML 资源的规范存放路径,通过优化配置可实现正常扫描;
  3. 配置验证成功:远程配置加载正常,配置冲突问题已解决,实现 “新旧 XML 路径共存”;
  4. 接口验证成功:调用自测接口,返回完整分页结果,无任何异常,自测用例全链路跑通。

自测接口返回结果(验证成功):

验证自带分页的老接口也是成功:

2. 核心经验沉淀(为项目重构储备)

本次自测最大的收获,不仅是掌握了 MyBatis-Plus 的引入与配置,更在于沉淀了一系列可用于未来项目重构的实践经验,分享给大家:

  1. 依赖适配经验:项目重构时,引入新工具(如 MyBatis-Plus),需先梳理现有依赖体系,清理冗余依赖,强制指定核心依赖版本,避免版本冲突;
  2. 配置优化经验:XML 资源路径规范化是项目重构的重要环节,可通过mybatis-plus.mapper-locations指定规范路径,同时需关注 “自定义配置与框架自动装配的优先级”,避免配置失效;
  3. 问题排查经验:遇到 XML 扫描失败、SQL 绑定异常时,可按 “资源打包→依赖冲突→配置优先级” 的顺序分层排查,高效定位问题根因;
  4. 平滑迁移经验:MyBatis 迁移 MyBatis-Plus 可实现 “零侵入兼容”,无需重构历史代码,可先实现 “新旧 XML 路径共存”,再分批迁移,降低重构风险;
  5. 自测前置经验:项目重构前,可通过自主自测,提前踩坑、排查问题,积累可落地的实践经验,避免正式重构时出现业务中断,提升重构效率。

六、学习心得与未来规划(分享收尾)

本次自主自测学习,不仅熟练掌握了 MyBatis-Plus 的核心用法、XML 路径规范的配置技巧,更深刻体会到 “提前技术储备、自主实践排查” 的重要性。作为后端开发,日常工作中,不能只满足于 “完成业务开发”,更要主动学习新工具、新规范,通过自主自测、踩坑复盘,积累项目重构、技术升级所需的经验。

同时,也深刻认识到,项目重构的核心是 “稳定、高效、规范”,而 MyBatis-Plus 的引入、jar包的管理,XML 路径的规范化,正是契合这一核心需求,也让我更加明确了未来的技术学习方向。

七、总结

本次自测学习分享,核心是记录自身 MyBatis 迁移 MyBatis-Plus、XML,POM 中jar包管理 路径规范的实践过程,沉淀项目重构所需的经验,也希望能为各位同事、同行提供一些参考。

项目重构不是一蹴而就的,需要提前技术储备、充分自测准备、科学规划流程。未来,我将继续保持自主学习、自主实践的态度,积累更多实用的技术经验,为项目发展、自身成长保驾护航。

技术分享帖持续更新中ing