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

相关推荐
zzzzzz3101 天前
9K Star 炸裂开源!这个 C 语言写的代码知识图谱,把 Linux 内核索引压缩到了 3 分钟
linux·服务器·sql
云技纵横3 天前
唯一索引 INSERT 死锁实战:5 秒复现交叉插入的 S 锁循环等待
sql·mysql
BD_Marathon5 天前
SQL学习指南——视图
数据库·sql
2601_962072555 天前
李梦娇常识4600问|题库|打印版
sql·华为od·华为·c#·华为云·.net·harmonyos
敲个大西瓜5 天前
mybatis拦截器插件实现数据库字段加解密
mybatis
HackTwoHub5 天前
Sqli-Scanner SQL注入SKILL自动化挖掘SQL注入,零依赖自动化SQL注入挖掘,赏金猎人
数据库·人工智能·sql·web安全·网络安全·自动化·系统安全
tianyuanwo5 天前
深入解析 RISC-V 虚拟化中的 UEFI 固件配置:从 XML 到 NVRAM 的生命周期管理
xml·linux·risc-v
Volunteer Technology5 天前
Flink Table API与SQL(一)
大数据·sql·flink
持敬chijing5 天前
Web渗透之SQL注入-常用sql语句
sql·安全·web安全·网络安全