Spring Data MongoDB Repository:如何用@Query注解排除空查询字段?
仅通过@Query注解实现Spring Data MongoDB动态条件查询
可以仅使用@Query注解结合SpEL表达式实现需求,核心是利用?#{}语法在注解中嵌入动态逻辑,直接生成合法的MongoDB查询文档,避免字符串转义问题。
实现方案1:手动拼接JSON字符串
适用于参数无特殊字符的场景,通过嵌套三元运算符判断参数有效性,组合对应的查询条件:
@Repository public interface BookRepo extends MongoRepository<Book, String> { @Query("?#{ " + "T(org.springframework.util.StringUtils).hasText(?0) ? " + "(T(org.springframework.util.StringUtils).hasText(?1) ? " + "'{\"author\": \"' + ?0 + '\", \"publisher\": \"' + ?1 + '\"}' : " + "'{\"author\": \"' + ?0 + '\"}') : " + "(T(org.springframework.util.StringUtils).hasText(?1) ? " + "'{\"publisher\": \"' + ?1 + '\"}' : " + "'{}') " + "}") List<Book> getAllBooksBy(String author, String publisher); }
代码说明:
?#{}用于包裹SpEL表达式,Spring会执行该表达式并将结果作为最终查询条件。- 借助
StringUtils.hasText()判断参数是否为非空非空白的有效内容。 - 通过三元运算符分支处理四种参数组合情况,生成对应的JSON格式查询文档:
- 两个参数都有效:生成包含
author和publisher的查询条件 - 仅
author有效:只保留author查询条件 - 仅
publisher有效:只保留publisher查询条件 - 两个参数都无效:返回空文档
{},查询所有书籍
- 两个参数都有效:生成包含
实现方案2:通过Map转JSON处理特殊字符
如果参数可能包含双引号、反斜杠等特殊字符,手动拼接字符串会导致JSON格式错误,可通过SpEL创建Map并转为JSON:
@Repository public interface BookRepo extends MongoRepository<Book, String> { @Query("?#{ " + "let conditions = new java.util.HashMap(); " + "if (T(org.springframework.util.StringUtils).hasText(?0)) { conditions.put('author', ?0); } " + "if (T(org.springframework.util.StringUtils).hasText(?1)) { conditions.put('publisher', ?1); } " + "new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(conditions) " + "}") List<Book> getAllBooksBy(String author, String publisher); }
代码说明:
- 创建
HashMap存储有效查询条件,仅当参数有效时才添加对应键值对。 - 使用Jackson的
ObjectMapper将Map转为合法JSON字符串,自动处理特殊字符的转义,保证查询格式正确。 - Spring Boot默认已包含Jackson依赖,无需额外引入。
这两种方案都完全基于@Query注解实现,无需扩展仓库接口、编写Mongo DSL代码或使用QueryByExample框架,符合你的需求。
内容的提问来源于stack exchange,提问作者takanuva15
相关产品推荐
相关产品推荐

