“动态 SQL 避免重复”一般有 两层含义,我会分别说明,并给出常见解决方案 + 示例,你可以对照自己的场景选用。
if (cond1) {
sql += " AND a = 1";
}
if (cond2) {
sql += " AND a = 1"; // 重复
}
<sql> + <include>(最常用)定义可复用 SQL 片段
<sql id="baseWhere">
WHERE 1=1
</sql>
<sql id="condA">
AND a = #{a}
</sql>
复用
<select id="query">
SELECT * FROM t
<include refid="baseWhere"/>
<if test="a != null">
<include refid="condA"/>
</if>
</select>
✅ 避免:
<where> / <trim> 自动处理重复❌ 错误写法
WHERE 1=1
AND a = #{a}
AND b = #{b}
✅ 正确写法
<where>
<if test="a != null">
AND a = #{a}
</if>
<if test="b != null">
AND b = #{b}
</if>
</where>
✅ 好处:
AND / OR<foreach> 避免 IN 条件重复❌ 重复拼接
AND id IN (1)
AND id IN (2)
✅ 正确
<if test="ids != null and ids.size() > 0">
AND id IN
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</if>
DISTINCTSELECT DISTINCT user_id FROM orders
⚠️ 注意:
DISTINCT 是对整行去重GROUP BYSELECT user_id, MAX(create_time)
FROM orders
GROUP BY user_id
✅ 适合:
<select id="query">
SELECT
<choose>
<when test="distinct">
DISTINCT *
</when>
<otherwise>
*
</otherwise>
</choose>
FROM t
<where>
<if test="name != null">
AND name = #{name}
</if>
</where>
</select>
<if test="a != null">
AND a = #{a}
</if>
<if test="a != null">
AND a = #{a}
</if>
✅ 解决:
<sql>| 场景 | 建议 |
|---|---|
| 条件多 | <where> + <if> |
| 公共 SQL | <sql> + <include> |
| IN 查询 | <foreach> |
| 去重 | DISTINCT / GROUP BY |
| 复杂动态 | Query Object / Criteria |
动态 SQL 避免重复 = SQL 片段复用 + 自动拼接 + 数据去重
如果你愿意,可以把你具体的 SQL 或 MyBatis XML贴出来,我可以直接帮你重构优化。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。