[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 = '技术部'

相关推荐
喜欢的名字被抢了4 小时前
MySQL核心机制:事务、锁与存储引擎
数据库·sql·mysql·教程
AI产品实战6 小时前
Gradle打包生成dependencies.xml详解
xml·java·gradle
阿演7 小时前
DataDjinn v0.2.11:SQL 编辑、AI 协作和表格操作继续打磨
数据库·人工智能·sql
山峰哥8 小时前
‌Explain实战:打开数据库执行计划的黑盒‌
大数据·服务器·数据库·sql·深度优先·宽度优先
Wang's Blog9 小时前
Java框架快速入门:深入MyBatis-Plus高级DML操作(ID策略·逻辑删除·乐观锁)
java·数据库·mybatis
RestCloud19 小时前
借助ETL工具,实现AI智能体+数据的落地
数据仓库·人工智能·sql·etl·etlcloud·数据集成平台·java脚本
上海云盾-小余21 小时前
网站频繁遭遇 SQL 注入溯源与原生漏洞修复全流程总结
数据库·sql
丑八怪大丑1 天前
MyBatis
mybatis
_Jimmy_1 天前
SQLAlchemy 复杂 SQL 执行指南与模板库
python·sql
2601_954916591 天前
ChatGPT 5.6 深度实践:用 AI 重构云成本治理体系,而不是简单“降本”
人工智能·sql·chatgpt·重构·测试用例