You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Data MongoDB多条件查询:@Query注解等价实现问询

Spring Data MongoDB 动态字段查询的@Query实现

首先先修正你原来的MongoTemplate代码,原代码存在两个问题:一是循环中未将键值对添加为查询条件,二是仅处理第一个Entry就直接返回,无法实现多条件查询,修正后的代码如下:

public List<Party> retrivePartyByQuery(Map<String, String> payload) {
    Query query = new Query();
    for (Map.Entry<String, String> entry : payload.entrySet()) {
        query.addCriteria(Criteria.where(entry.getKey()).is(entry.getValue()));
    }
    return mongoTemplate.find(query, Party.class);
}

接下来是用@Query注解实现等价逻辑的方案,由于查询字段和值是动态传入的,需要借助Spring表达式语言(SpEL)来解析Map参数:

import org.springframework.data.mongodb.repository.Query;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
import java.util.Map;

public interface PartyRepository extends CrudRepository<Party, String> {

    @Query(value = "?0")
    List<Party> findByDynamicQuery(Map<String, String> payload);
}

说明:

  • ?0是SpEL的参数占位符,代表方法的第一个参数(也就是传入的payload Map),Spring Data MongoDB会自动将这个Map转换为MongoDB的查询文档(等价于{key1: value1, key2: value2,...})。
  • 这种方式会将Map中的所有键值对作为AND条件进行匹配,和修正后的MongoTemplate逻辑完全一致。

如果需要更灵活的控制(比如部分字段用模糊匹配),也可以用SpEL手动构建查询条件:

@Query(value = "#{T(org.springframework.data.mongodb.core.query.Criteria).fromDocument(?0).getCriteriaObject()}")
List<Party> findByDynamicCriteria(Map<String, String> payload);

补充:

如果你的查询场景大部分是简单的等值匹配,也可以使用Spring Data的QueryByExampleExecutor接口,无需编写@Query:

import org.springframework.data.repository.query.QueryByExampleExecutor;

public interface PartyRepository extends CrudRepository<Party, String>, QueryByExampleExecutor<Party> {
}

使用时构建Example对象:

public List<Party> retrivePartyByQuery(Map<String, String> payload) {
    Party partyExample = new Party();
    payload.forEach((key, value) -> {
        // 通过反射设置对应字段的值,或者使用BeanUtils
        try {
            Field field = Party.class.getDeclaredField(key);
            field.setAccessible(true);
            field.set(partyExample, value);
        } catch (Exception e) {
            throw new IllegalArgumentException("无效的字段名:" + key);
        }
    });
    return (List<Party>) partyRepository.findAll(Example.of(partyExample));
}

内容的提问来源于stack exchange,提问作者Ahmad Irfaan Hibatullah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 17:10:37