测试动态 SQL(如 MyBatis 的 <if>/<foreach>/<choose>、字符串拼接 SQL、条件分支 SQL)的核心目标是:验证不同输入条件下最终生成的 SQL 是否正确、安全、高效。
下面按方法 → 工具 → 示例 → 常见坑来系统说明。
动态 SQL 本质上测试三件事:
SqlSession + Mapper示例(MyBatis)
@Test
void testDynamicSql() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.selectUser(
new UserQuery(null, "Tom", null)
);
// 断言结果 + SQL 日志
}
打开 SQL 日志:
logging:
level:
com.xxx.mapper: debug
开启日志,观察最终 SQL:
select * from user
where name = ?
and age > ?
✅ 检查:
and@MybatisTest
class UserMapperTest {
@Autowired UserMapper mapper;
}
Interceptor@Intercepts({@Signature(type=Executor.class, method="update", args={MappedStatement.class, Object.class})})
或 JUnit 中捕获 PreparedStatement
动态 SQL 分支多,建议:
| 场景 | 示例 |
|---|---|
| 单条件 | 只传 name |
| 多条件 | name + age |
| 空参数 | 全 null |
| 空集合 | list 为空 |
| 边界值 | age = 0 |
<select id="selectUser">
select * from user
<where>
<if test="name != null">
and name = #{name}
</if>
<if test="age != null">
and age > #{age}
</if>
</where>
</select>
selectUser(null, null); // where 不生成
selectUser("Tom", null); // name
selectUser(null, 18); // age
selectUser("Tom", 18); // both
<if> 中写 status == 0(MyBatis 中 0 可能被当 false)list.size() > 0 忘记判 nullwhere 后多 and✅ 建议:
<where> / <set>#{} 而非 ${}如果你愿意,可以:
我可以直接帮你设计针对性测试用例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。