动态 SQL 和普通 SQL(又叫静态 SQL)的主要区别在于 SQL 语句是否在编译期确定,以及 是否可以在运行时动态拼接/生成。下面从多个角度对比说明,并给出典型使用场景。
| 对比项 | 普通 SQL(静态 SQL) | 动态 SQL |
|---|---|---|
| SQL 是否固定 | ✅ 编译期已确定 | ❌ 运行时才确定 |
| 是否可拼接条件 | ❌ 不能 | ✅ 可以 |
| 灵活性 | 低 | 高 |
| 编译优化 | 好(可预编译) | 较差(部分无法预编译) |
| SQL 注入风险 | 低(参数化时) | 高(拼接字符串时) |
| 可读性 | 好 | 稍差 |
| 常见使用场景 | 固定查询 | 条件不确定的查询 |
普通 SQL 是指在代码中 SQL 语句是固定写死的,参数通常通过占位符(? 或 @参数)传入。
String sql = "SELECT * FROM user WHERE id = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, 10);
✅ SQL 结构不变
✅ 只有参数变化
✅ 数据库可以预编译 SQL
动态 SQL 是指 SQL 语句在 运行时根据条件动态拼接生成,例如:
String sql = "SELECT * FROM user WHERE 1=1";
if (name != null) {
sql += " AND name = '" + name + "'";
}
⚠️ 有严重 SQL 注入风险(不推荐)
<select id="findUser" parameterType="map" resultType="User">
SELECT * FROM user
<where>
<if test="name != null">
AND name = #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
</where>
</select>
✅ SQL 在运行时动态生成
✅ 使用 #{} 防止 SQL 注入
✅ 条件灵活
<if>/<choose>/<foreach>EXEC('SELECT * FROM user WHERE id = ' + @id)
✅ 正确做法:
动态 SQL + 参数化查询(占位符)
✅ 适合使用动态 SQL 的场景:
❌ 不适合:
普通 SQL 是“写死的 SQL”,动态 SQL 是“运行期拼出来的 SQL”。
动态 SQL 更灵活,但复杂性、性能和安全风险也更高。
如果你愿意,我也可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。