如何根据参数合并SQL计数查询实现类别名称唯一性校验
合并SQL查询实现条件分支逻辑
嘿,你完全不用写两个SQL或者在Java里做分支判断,我们可以用一个通用的SQL语句来同时处理parentUid为null和非null的情况,逻辑和你写的伪代码完全一致。
合并后的SQL语句
直接用这个替代原来的两个查询:
SELECT count(*) FROM TABLE WHERE (parent_uid = :parent_uid OR (:parent_uid IS NULL AND parent_uid IS NULL)) AND name = :name AND tenant_uid = :tenant_uid
逻辑解释
- 当传入的
parentUid(即:parent_uid参数)为null时::parent_uid IS NULL为真,条件简化为parent_uid IS NULL,同时匹配name和tenant_uid的条件,和你第一个查询逻辑一致。 - 当传入的
parentUid非null时::parent_uid IS NULL为假,此时只有parent_uid = :parent_uid生效,同样匹配name和tenant_uid,和你第二个查询逻辑一致。
Java方法适配
只需要把你的GET_ECATEGORY_COUNT常量替换成上面的SQL即可,现有的参数绑定逻辑完全不用改——MapSqlParameterSource已经正确传入了所有参数,jdbcTemplate会自动处理null参数的绑定:
// 定义常量(替换原来的GET_ECATEGORY_COUNT) private static final String GET_ECATEGORY_COUNT = """ SELECT count(*) FROM TABLE WHERE (parent_uid = :parent_uid OR (:parent_uid IS NULL AND parent_uid IS NULL)) AND name = :name AND tenant_uid = :tenant_uid """; /** * returns the count of categories that contain all parameters passed * @param parentUid parent category uid * @param name category name * @param tenantUid tenant uid * @return count of records */ public int checkCategoryUniqueName(UUID parentUid, String name, UUID tenantUid) { MapSqlParameterSource map = new MapSqlParameterSource() .addValue("parent_uid", parentUid) // 注意参数名要和SQL里的占位符一致 .addValue("name", name) .addValue("tenant_uid", tenantUid); return jdbcTemplate.queryForObject(GET_ECATEGORY_COUNT, map, Integer.class); }
小贴士:确保SQL里的占位符名称和
addValue里的参数名完全对应,比如:parent_uid对应"parent_uid"参数。
额外优化(可选)
有些数据库支持更简洁的写法,比如PostgreSQL的IS NOT DISTINCT FROM,可以把条件简化成:
SELECT count(*) FROM TABLE WHERE parent_uid IS NOT DISTINCT FROM :parent_uid AND name = :name AND tenant_uid = :tenant_uid
这个运算符会自动处理null的情况:当两边都是null时返回真,非null时判断是否相等,逻辑和之前的写法完全一致,但代码更短。不过这个语法不是所有数据库都支持(比如MySQL就没有),所以要看你用的数据库类型选择。
内容的提问来源于stack exchange,提问作者Алиса Ламехова
相关产品推荐
相关产品推荐

