目录
1. 注意事项
2. 示例代码
2.1 实体类
2.2 Mapper 接口
2.3 测试类
3. 运行效果
4. 总结
在实际项目中,虽然 MyBatis-Plus 提供了丰富的内置方法和 QueryWrapper
条件构造器,但有时我们需要 自定义 SQL 来实现更复杂的查询逻辑。
MyBatis-Plus 从 3.0.7 版本开始支持 Wrapper 自定义 SQL,结合 ${ew.customSqlSegment}
,可以在 XML 或注解中编写动态 SQL,灵活性更高。
1. 注意事项
在使用 Wrapper 自定义 SQL 时,需要注意以下几点:
-
版本要求
MyBatis-Plus 版本必须 ≥ 3.0.7。
低版本不支持customSqlSegment
。 -
参数命名
Wrapper 参数必须命名为ew
,
或者用@Param(Constants.WRAPPER)
明确指定。 -
SQL 引用方式
在 SQL 语句中,使用${ew.customSqlSegment}
引入 Wrapper 生成的 SQL 条件片段。 -
不支持基于 entity 的 where
自定义 SQL 时,Wrapper 不会基于实体类自动生成 where 条件,需要自己写 SQL。
2. 示例代码
2.1 实体类
文件:User.java
package com.example.pojo;import lombok.Data;@Data
public class User {private Long id;private String username;private String info;private Integer balance;
}
2.2 Mapper 接口
文件:UserMapper.java
package com.example.mapper;import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.example.pojo.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;import java.util.List;public interface UserMapper extends BaseMapper<User> {// 使用 Wrapper 自定义 SQL@Select("SELECT id, username, info, balance FROM user ${ew.customSqlSegment}")List<User> selectByCustomSql(@Param(Constants.WRAPPER) Wrapper<User> wrapper);
}
2.3 测试类
文件:UserMapperTest.java
package com.example;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.mapper.UserMapper;
import com.example.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;@SpringBootTest
public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testvoid testSelectByCustomSql() {QueryWrapper<User> wrapper = new QueryWrapper<User>().like("username", "o") // 模糊匹配 username.ge("balance", 1000); // balance >= 1000List<User> users = userMapper.selectByCustomSql(wrapper);users.forEach(System.out::println);}
}
3. 运行效果
生成的 SQL:
SELECT id, username, info, balance
FROM user
WHERE (username LIKE '%o%' AND balance >= 1000)
返回结果:
User(id=1, username=Tom, info=喜欢运动, balance=2000)
User(id=3, username=Bob, info=游戏达人, balance=1500)
4. 总结
-
@Select("... ${ew.customSqlSegment}")
可以结合 Wrapper 动态拼接条件,避免大量 XML 配置。 -
参数必须用
@Param(Constants.WRAPPER)
标记,或者命名为ew
。 -
灵活度比单纯
BaseMapper
的内置方法更高,适合需要部分自定义 SQL 的场景。
👉 建议在 复杂 SQL + 动态条件的场景下使用,简化 SQL 管理的同时又保留了 MyBatis-Plus 的便利性。