在 动态 SQL 中传参数,常见做法取决于你使用的是哪种技术(MyBatis、JDBC、存储过程、不同数据库等)。下面我用 最常见 + 面试/实战场景 给你系统讲一下。
Mapper 接口
List<User> findUsers(
@Param("name") String name,
@Param("age") Integer age
);
XML 动态 SQL
<select id="findUsers" resultType="User">
SELECT * FROM user
<where>
<if test="name != null">
AND name = #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
</where>
</select>
✅ #{}:
UserQuery query = new UserQuery();
query.setName("Tom");
query.setAge(18);
<select id="findUsers" parameterType="UserQuery" resultType="User">
SELECT * FROM user
<where>
<if test="name != null">
AND name = #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
</where>
</select>
Map<String, Object> map = new HashMap<>();
map.put("name", "Tom");
map.put("age", 18);
<select id="findUsers" parameterType="map" resultType="User">
SELECT * FROM user
<where>
<if test="name != null">
AND name = #{name}
</if>
</where>
</select>
${} 和 #{} 的区别(面试高频 ❗)| 写法 | 是否预编译 | 是否安全 | 使用场景 |
|---|---|---|---|
#{} |
✅ 是 | ✅ 防注入 | 传值(推荐) |
${} |
❌ 否 | ❌ 有风险 | 动态表名、排序字段 |
<!-- 排序字段(只能 ${}) -->
ORDER BY ${column}
⚠️ 不要用 ${} 传用户输入值
String sql = "SELECT * FROM user WHERE 1=1";
List<Object> params = new ArrayList<>();
if (name != null) {
sql += " AND name = ?";
params.add(name);
}
PreparedStatement ps = conn.prepareStatement(sql);
for (int i = 0; i < params.size(); i++) {
ps.setObject(i + 1, params.get(i));
}
✅ 用 ? 占位符
✅ 参数通过 setXxx() 传
PREPARE stmt FROM 'SELECT * FROM user WHERE age = ?';
SET @a = 18;
EXECUTE stmt USING @a;
前端参数
↓
Controller(@RequestParam / @RequestBody)
↓
Service
↓
Mapper(动态 SQL)
↓
数据库
❌ 用 ${} 传用户输入
❌ 动态 SQL 拼字符串
❌ 参数类型不匹配
❌ 忘记 <where> 导致 SQL 语法错误
动态 SQL 传参数的核心:用占位符 + 预编译,参数通过接口 / 对象 / Map 传入,避免字符串拼接。
如果你愿意,我可以:
你现在是 面试准备 还是 项目实战?
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。