MyBatis 的 <sql> 和 <include> 是实现 XML 中动态 SQL 片段复用的核心机制,通过 <sql> 定义无顶层关键字的可参数化片段,再用 <include> 引入并支持 property 传参,实现安全、模块化、可嵌套的 SQL 复用。

MyBatis 的 `
定义可复用的 `` 片段
使用 `
id, username, email, status, create_time
</sql>
<sql id="user_condition">
<if test="username != null and username != ''">
AND username LIKE CONCAT('%', #{username}, '%')
</if>
<if test="status != null">
AND status = #{status}
</if>
</sql>
在语句中用 `` 引入并传递参数
`
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
SELECT
<include refid="user_columns"/>
FROM user
WHERE 1=1
<include refid="user_condition">
<property name="username" value="#{query.username}"/>
<property name="status" value="#{query.status}"/>
</include>
</select>
注意:`
立即学习“Java免费学习笔记(深入)”;
嵌套 `` 与作用域注意事项
一个 `
- 所有 `
` 展开后必须构成语法合法的 SQL —— 例如不要在 ` ` 片段里写 `WHERE`,除非你确定每次引入都处于 WHERE 子句位置 - 参数作用域是扁平的:被 `
` 的片段直接访问外层传入的参数对象(如 `#{id}`),无需额外声明;` ` 是覆盖/补充方式,非必需 - ID 全局唯一:`
` 的 id 在整个 Mapper XML 中不能重复,否则启动报错
实战技巧:避免常见陷阱
-
别在 `
` 里写分号或注释 —— MyBatis 不解析 SQL 注释,且分号可能破坏语句结构 -
复杂条件建议拆成多个 `
` ,比如 `base_condition`、`admin_only_condition`,再组合使用,提升可读性与复用率 -
字段列表尽量用 `
` 封装 ,尤其涉及多表 JOIN 或结果映射时,避免硬编码导致 `resultMap` 维护脱节 - 如果片段需区分 INSERT/UPDATE 字段(如排除主键或时间戳),可用 `
` 或自定义属性判断执行上下文

















