@SelectProvider 是 MyBatis 动态 SQL 的核心方式,通过 Java 方法生成 SQL,支持复杂条件、复用与 IDE 辅助;需编写返回 String 的 Provider 方法,用 #{xxx} 防注入,Mapper 接口通过 type 和 method 指定。

MyBatis 的 @SelectProvider 注解是处理动态 SQL 的核心手段之一,它把 SQL 构建逻辑从 XML 或静态注解中抽离出来,交由 Java 方法控制,适合条件多变、结构复杂、需复用或需 IDE 支持的场景。
Provider 类怎么写
Provider 类是一个普通 Java 类,里面的方法返回 String 类型的完整 SQL 语句。方法参数可以是单个对象、Map 或多个带 @Param 标注的参数。
- 推荐使用实体类或 Map 传参,便于条件判断和字段映射
- SQL 拼接建议用 StringBuilder 避免字符串频繁创建;若追求可读性与安全,可用 MyBatis 自带的
SQL工具类(需继承org.apache.ibatis.jdbc.SQL) - 注意 SQL 中的占位符写法:用
#{xxx}而不是拼接字符串,防止 SQL 注入
Mapper 接口怎么配
在 Mapper 接口中,用 @SelectProvider 明确指定 Provider 类和方法名:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
type填 Provider 类的 Class 对象(如CheckSummaryProvider.class) -
method填该类中返回 SQL 字符串的 public 方法名(如"selectCheckSummary") - 接口方法的参数会自动传入 Provider 方法,类型必须匹配(例如接口传
@Param("startDate") String s,Provider 方法参数就得是Map<String, Object>或对应命名参数)
常见动态拼接技巧
实际开发中,常需根据参数有无、取值不同来增删 WHERE 条件、JOIN 子句或聚合字段:
立即学习“Java免费学习笔记(深入)”;
- 用 if 判断参数非空再追加条件,例如:
if (params.get("status") != null) sql.append(" AND status = #{status}"); - 对日期范围、模糊查询、IN 列表等,统一用
#{}占位,避免手动拼接引号和 TO_DATE 等函数(数据库兼容性更好) - 子查询或 UNION 场景,可在 Provider 方法里分段构建,再组合成完整 SQL
和其他方式对比要注意什么
@SelectProvider 不是万能替代品,选型要看实际需求:
- 简单固定 SQL 直接用
@Select("SELECT * FROM user WHERE id = #{id}")更轻量 - 中等复杂度、条件有限的查询,XML 中的
<if>和<where>更直观 - @SelectProvider 优势在于 Java 逻辑强、可调试、易单元测试、支持复杂分支和循环,但要小心 SQL 拼错或注入风险

















