温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何测试动态SQL逻辑

发布时间:2026-10-20 02:10:41 来源:亿速云 阅读:98 作者:小樊 栏目:数据库

测试动态 SQL(如 MyBatis 的 <if>/<foreach>/<choose>、字符串拼接 SQL、条件分支 SQL)的核心目标是:验证不同输入条件下最终生成的 SQL 是否正确、安全、高效。

下面按方法 → 工具 → 示例 → 常见坑来系统说明。


一、测试思路(先想清楚测什么)

动态 SQL 本质上测试三件事:

  1. SQL 是否生成正确
    • 条件命中 / 未命中
    • 多条件组合
  2. 参数绑定是否正确
    • 空值、null、空集合
  3. 边界与异常
    • 全空条件
    • SQL 注入风险

二、常见测试方式(由浅入深)

1️⃣ 单元测试(最推荐)

✅ MyBatis 官方方式

  • 使用 SqlSession + Mapper
  • 打印或拦截最终 SQL

示例(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

2️⃣ SQL 日志验证(最实用)

开启日志,观察最终 SQL:

select * from user 
where name = ? 
  and age > ?

✅ 检查:

  • 条件是否出现
  • 是否多/少 and
  • 是否错误拼接

3️⃣ 使用 MyBatis 测试框架

✅ mybatis-test / mybatis-spring-test

  • 内嵌 H2 数据库
  • 真实执行 SQL
@MybatisTest
class UserMapperTest {
    @Autowired UserMapper mapper;
}

4️⃣ 拦截 SQL(精确验证)

使用 Interceptor

@Intercepts({@Signature(type=Executor.class, method="update", args={MappedStatement.class, Object.class})})

或 JUnit 中捕获 PreparedStatement


5️⃣ 覆盖率测试(条件组合)

动态 SQL 分支多,建议:

场景 示例
单条件 只传 name
多条件 name + age
空参数 全 null
空集合 list 为空
边界值 age = 0

三、示例:典型动态 SQL 测试

Mapper

<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

四、防坑指南(非常重要)

❌ 常见错误

  1. <if> 中写 status == 0(MyBatis 中 0 可能被当 false)
  2. list.size() > 0 忘记判 null
  3. 字符串拼接导致 SQL 注入
  4. where 后多 and

✅ 建议:

  • 用 <where> / <set>
  • 用 #{} 而非 ${}
  • 集合先判空

五、进阶建议

  • ✅ 配合 H2 / Testcontainers 做集成测试
  • ✅ 用 JaCoCo 看动态分支覆盖率
  • ✅ 对关键 SQL 写 Golden SQL 测试

如果你愿意,可以:

  • 告诉我你用的是 MyBatis / JPA / 原生 JDBC
  • 或贴一段 动态 SQL 代码

我可以直接帮你设计针对性测试用例。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手