全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-20 6 分钟 ✍️ juanwangdev

sql 片段复用

MyBatis 提供 <sql><include> 标签实现 SQL 片段的提取与引用,避免在多个 Statement 中重复编写相同 SQL。

基本语法

定义 SQL 片段:

XML
<sql id="baseColumns">
    id, name, age, email, create_time
</sql>

引用 SQL 片段:

XML
<select id="findAll" resultType="User">
    SELECT <include refid="baseColumns"/> FROM user
</select>

列定义复用

最常见场景是提取字段列表:

XML
<sql id="userColumns">
    u.id, u.name, u.age, u.email, u.status,
    u.create_time, u.update_time
</sql>

<select id="findById" resultType="User">
    SELECT <include refid="userColumns"/> FROM user u WHERE u.id = #{id}
</select>

<select id="findByPage" resultType="User">
    SELECT <include refid="userColumns"/>
    FROM user u
    <where>
        <if test="status != null">u.status = #{status}</if>
    </where>
    LIMIT #{offset}, #{limit}
</select>

WHERE 条件复用

公共查询条件可提取复用:

XML
<sql id="statusCondition">
    AND status != 'DELETED'
</sql>

<select id="findActive" resultType="User">
    SELECT * FROM user
    <where>
        <include refid="statusCondition"/>
        <if test="age != null">AND age &gt;= #{age}</if>
    </where>
</select>

跨 Mapper 复用

SQL 片段支持跨文件引用,使用 namespace 前缀:

XML
<!-- BaseMapper.xml -->
<sql id="baseQuery">
    SELECT id, name, age FROM user WHERE status = 'ACTIVE'
</sql>

<!-- UserMapper.xml -->
<select id="findActiveUsers" resultType="User">
    <include refid="com.example.mapper.BaseMapper.baseQuery"/>
    <if test="name != null">AND name LIKE CONCAT('%', #{name}, '%')</if>
</select>

跨 Mapper 引用时,refid 格式为 namespace.sqlId

动态片段

SQL 片段中可包含动态标签,引用时传入参数:

XML
<sql id="orderByClause">
    <if test="sortField != null">
        ORDER BY ${sortField} ${sortDirection}
    </if>
</sql>

<select id="findWithSort" resultType="User">
    SELECT * FROM user
    <where>
        <if test="name != null">name LIKE CONCAT('%', #{name}, '%')</if>
    </where>
    <include refid="orderByClause"/>
</select>

JOIN 语句复用

多表关联查询的 JOIN 部分也可提取:

XML
<sql id="userRoleJoin">
    JOIN user_role ur ON u.id = ur.user_id
    JOIN role r ON ur.role_id = r.id
</sql>

<select id="findUserWithRole" resultType="UserVO">
    SELECT u.id, u.name, r.name as role_name
    FROM user u
    <include refid="userRoleJoin"/>
    WHERE u.status = 'ACTIVE'
</select>

注意事项

  • <include> 是纯文本替换,不参与 SQL 注入防护,${} 变量在 include 中直接拼接
  • <sql> 内部可包含动态标签(if/where 等),但 <include> 只负责静态引用
  • 跨 Mapper 引用时 namespace 必须与 <mapper namespace="..."> 一致
  • 修改 <sql> 内容会影响所有引用处,变更需谨慎

要点总结

  • <sql> 提取公共 SQL 片段,<include refid="..."> 引用,减少重复代码
  • 适用于列定义、WHERE 条件、JOIN、ORDER BY 等场景
  • 支持跨 Mapper 引用,refid 格式为 namespace.sqlId
  • SQL 片段可包含动态标签,引用时仍是静态文本替换
  • 修改片段影响全局引用处,需评估影响范围

📝 发现内容有误?点击此处直接编辑

← 上一篇 set 更新字段
下一篇 → trim 自定义裁剪
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库