动态 SQL 拼接如果写得不好,很容易出现拼接字符串混乱、易出错、难维护、SQL 注入风险等问题。下面从思路 → 常见方案 → 示例几个层面,讲怎么“简化”。
<if> + <where> 自动处理 AND<select id="queryUser" resultType="User">
SELECT * FROM user
<where>
<if test="name != null">
AND name = #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
</where>
</select>
✅ 优点:
WHERE 1=1AND<choose> 替代 if-else<choose>
<when test="type == 'A'">
AND status = 'A'
</when>
<when test="type == 'B'">
AND status = 'B'
</when>
<otherwise>
AND status = 'C'
</otherwise>
</choose>
<foreach> 简化 IN 查询AND id IN
<foreach collection="ids" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
@SelectProvider(type = UserSql.class, method = "query")
List<User> query(User user);
public class UserSql {
public String query(User u) {
return new SQL(){{
SELECT("*");
FROM("user");
if (u.getName() != null) WHERE("name = #{name}");
if (u.getAge() != null) WHERE("age = #{age}");
}}.toString();
}
}
✅ 适合:SQL 不复杂但想少写 XML
QueryWrapper<User> qw = new QueryWrapper<>();
qw.eq(name != null, "name", name);
qw.ge(age != null, "age", age);
userMapper.selectList(qw);
✅ 优点:
List<User> findByNameAndAge(String name, Integer age);
或:
Specification<User> spec = (root, q, cb) -> {
List<Predicate> list = new ArrayList<>();
if (name != null) list.add(cb.equal(root.get("name"), name));
return cb.and(list.toArray(new Predicate[0]));
};
✅ 适合:简单业务、快速开发
String sql = "SELECT * FROM user WHERE 1=1 ";
if (name != null) sql += " AND name = '" + name + "'";
问题:
动态 SQL 拼接的终极简化 = 条件判断交给框架,SQL 结构保持固定
如果你愿意,可以告诉我:
我可以直接帮你写一版“最简实现”。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。