[Mybatis] XML 方式实现 MP 自定义 SQL + 条件构造器

1. 流程

  1. 配置 mapper XML 扫描路径
  2. 在 Mapper 接口中定义方法
  3. 编写对应的 XML SQL
  4. 测试调用

2. 逐行代码详解

2.1 配置 mapper 路径(application.yml)

复制代码
mybatis-plus:
  mapper-locations: "classpath*:/mapper/**.xml" # Mapper.xml
  • 作用:告诉 Spring Boot,去哪里找 MyBatis 的 XML 映射文件
  • 路径规则:classpath*:/mapper/**.xml 表示 resources/mapper/ 目录下所有 .xml 文件都会被扫描到

2.2 Mapper 接口定义

复制代码
@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
    List<UserInfo> queryUserByCustom2(@Param(Constants.WRAPPER)Wrapper<UserInfo> wrapper);
}
  • @Mapper:让 MyBatis 识别这个接口
  • @Param(Constants.WRAPPER):
    • 关键注解,值就是 ew
    • 告诉 MyBatis,这个参数在 XML 里要用 ${ew.customSqlSegment} 来引用
  • 方法名 queryUserByCustom2 要和 XML 里的 id 完全一致

2.3 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.bite.mybatis.plus.mapper.UserInfoMapper">

    <select id="queryUserByCustom2">
        select id,username,password,age FROM user_info ${ew.customSqlSegment}
    </select>

</mapper>
  • namespace:必须和 Mapper 接口的全类名一致
  • <select id="queryUserByCustom2">:id 必须和接口里的方法名完全一致
  • ${ew.customSqlSegment}:
    • 核心功能,会自动把 Wrapper 里的条件,转换成完整的 WHERE ... 片段
    • 比如传了 .eq("username","admin"),就会生成 WHERE username = 'admin'

2.4. 测试调用

复制代码
@Test
void testQueryUserByCustom2(){
    QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>()
            .eq("username","admin");
    userInfoMapper.queryUserByCustom2(queryWrapper).forEach(System.out::println);
}
  • 最终执行的 SQL:

    select id,username,password,age FROM user_info WHERE username = 'admin'


3.关键原理

XML 方式和注解方式的核心逻辑完全一样:

  • 你在 XML 里写 SELECT ... FROM ... 实现自定义 SQL
  • 通过 ${ew.customSqlSegment} 接收 Wrapper 条件,自动拼接 WHERE 子句
  • 区别只是 SQL 写在 XML 里,更适合复杂 SQL、多表联查等场景

4.易错点避坑

  1. namespace 写错 :必须和 Mapper 接口的全类名完全一致,否则会报 Invalid bound statement 错误
  2. 方法名不匹配 :XML 里的 id 必须和接口里的方法名完全一致
  3. 参数注解必须写 :@Param(Constants.WRAPPER) 不能少,否则 XML 里找不到 ew 对象
  4. 路径配置正确 :mapper-locations 要配置对,否则 XML 文件不会被加载

5. 和注解方式的对比

|--------|------------------|-------------------|-------------|
| 方式 | 优点 | 缺点 | 适用场景 |
| 注解方式 | 简单快捷,不用写 XML | 复杂 SQL 可读性差,不方便维护 | 简单查询、快速开发 |
| XML 方式 | 复杂 SQL 可读性强,方便维护 | 需要额外写 XML 文件 | 多表联查、复杂条件查询 |


6. 多表联查的 XML 写法

复制代码
<select id="queryUserWithDept">
    SELECT u.id, u.username, u.age, d.dept_name
    FROM user_info u
    LEFT JOIN dept d ON u.dept_id = d.id
    ${ew.customSqlSegment}
</select>
  • 测试时传 Wrapper 条件:

    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.gt("u.age", 18).eq("d.dept_name", "技术部");

  • 自动生成 SQL:

    SELECT u.id, u.username, u.age, d.dept_name
    FROM user_info u
    LEFT JOIN dept d ON u.dept_id = d.id
    WHERE u.age > 18 AND d.dept_name = '技术部'

相关推荐
泡海椒1 小时前
深度解析JQuick-SQL SQL解析与AST生成机制|分布式SQL原理
数据库·分布式·sql
步行cgn1 小时前
Spring MVC 核心配置文件详解:springmvc.xml 每一行配置的意义
xml·spring·mvc
悟道书生3 小时前
若依 RBAC 权限控制学习笔记
java·网络·笔记·sql·学习·vue
景熙55233 小时前
2.什么是业务后台系统
java·spring·tomcat·mybatis·jdbc
John_Hui6 小时前
MySQL基础知识
数据库·sql·mysql·1024程序员节
泡海椒6 小时前
深度解析JQuick-SQL 逻辑计划到物理计划生成机制|分布式SQL原理
数据库·分布式·sql
猫咪很可爱1 天前
MySQL 视图与只读用户:安全查询的完整实践指南
数据库·sql·mysql
2601_962885721 天前
AkShare 和 Tushare 哪个好?区别、场景与选型
mybatis
三垣网安1 天前
某某大学心理健康教育平台弱口令及SQL注入漏洞
数据库·sql
泡海椒1 天前
JQuick-SQL “数据源 SPI”辨析:应用适配器与 Function SPI 的正确边界
数据库·驱动开发·sql