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

相关推荐
HalvmånEver10 小时前
MySQL的增删改查命令合集合集
数据库·sql·oracle
不剪发的Tony老师11 小时前
dblab:一款基于终端的交互式数据库客户端
数据库·sql
夕除12 小时前
springboot--06
数据库·spring boot·mybatis
运维小子12 小时前
JumpServer Applet 发布自定义远程应用:Oracle SQL Developer 自动登录
数据库·sql·oracle·jumpserver
曹牧15 小时前
Oracle:将包含属性(Attributes)的 XML 数据解析为表格数据
xml·数据库·oracle
Java成神之路-15 小时前
MyBatis一级缓存与二级缓存深度解析
mybatis
上海云盾商务经理杨杨15 小时前
Web渗透核心漏洞:SQL注入漏洞测试与修复实战
数据库·sql·安全
身如柳絮随风扬16 小时前
MyBatis 与 Spring 中的设计模式
spring·设计模式·mybatis
Irene199117 小时前
(课堂笔记)游标与动态SQL(EXECUTE IMMEDIATE):使用 CHR(39) 替代拼接单引号
sql