分享免费的编程资源和教程

网站首页 > 技术教程 正文

使用 MongoRepository 实现动态查询

goqiw 2025-03-30 16:29:23 技术教程 12 ℃ 0 评论

在 Spring Data MongoDB 中,MongoRepository 本身并不直接支持类似 JPA Specification 的动态查询功能。不过,我们可以通过以下四种方式实现动态查询:


方法 1:使用@Query注解和 SpEL 表达式

通过 @Query 注解和 SpEL(Spring Expression Language)表达式,可以在 MongoRepository 中实现简单的动态查询。

示例:动态查询用户

import org.springframework.data.mongodb.repository.Query;
import org.springframework.data.mongodb.repository.MongoRepository;

import java.util.List;

public interface UserRepository extends MongoRepository {
    @Query("{ 'name' : ?0, 'age' : { $gte: ?1, $lte: ?2 } }")
    List findByNameAndAgeBetween(String name, int minAge, int maxAge);
}

使用

List users = userRepository.findByNameAndAgeBetween("Alice", 20, 30);

局限性:

  • 只能实现简单的动态查询,无法根据条件动态拼接查询。

方法 2:结合MongoTemplate实现动态查询

如果需要更灵活的动态查询,可以结合 MongoTemplate 来实现。虽然这不是直接使用 MongoRepository,但可以在服务层中封装动态查询逻辑。

示例:动态查询用户

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserService {
    @Autowired
    private MongoTemplate mongoTemplate;

    public List findUsers(String name, Integer minAge, Integer maxAge) {
        Query query = new Query();
        if (name != null) {
            query.addCriteria(Criteria.where("name").is(name));
        }
        if (minAge != null && maxAge != null) {
            query.addCriteria(Criteria.where("age").gte(minAge).lte(maxAge));
        }
        return mongoTemplate.find(query, User.class);
    }
}

使用

List users = userService.findUsers("Alice", 20, 30);

方法 3:自定义 Repository 实现

如果需要将动态查询逻辑封装到 MongoRepository 中,可以通过自定义 Repository 实现。

步骤 1:定义自定义 Repository 接口

import java.util.List;

public interface CustomUserRepository {
    List findUsers(String name, Integer minAge, Integer maxAge);
}

步骤 2:实现自定义 Repository

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public class CustomUserRepositoryImpl implements CustomUserRepository {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public List findUsers(String name, Integer minAge, Integer maxAge) {
        Query query = new Query();
        if (name != null) {
            query.addCriteria(Criteria.where("name").is(name));
        }
        if (minAge != null && maxAge != null) {
            query.addCriteria(Criteria.where("age").gte(minAge).lte(maxAge));
        }
        return mongoTemplate.find(query, User.class);
    }
}

步骤 3:扩展MongoRepository

import org.springframework.data.mongodb.repository.MongoRepository;

public interface UserRepository extends MongoRepository, CustomUserRepository {
}

使用

List users = userRepository.findUsers("Alice", 20, 30);

方法 4:使用Querydsl实现动态查询

Querydsl 是一个强大的查询框架,支持动态查询。Spring Data MongoDB 也支持 Querydsl。

步骤 1:添加依赖

在 pom.xml 中添加 Querydsl 依赖:


    com.querydsl
    querydsl-mongodb
    5.0.0


    com.querydsl
    querydsl-apt
    5.0.0
    provided

步骤 2:生成 Q 类

通过 maven-compiler-plugin 生成 Querydsl 的 Q 类:


    com.mysema.maven
    apt-maven-plugin
    1.1.3
    
        
            
                process
            
            
                target/generated-sources/java
                org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor
            
        
    

步骤 3:定义 Repository

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;

public interface UserRepository extends MongoRepository, QuerydslPredicateExecutor {
}

步骤 4:使用 Querydsl 动态查询

import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;

import java.util.List;

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    public List findUsers(String name, Integer minAge, Integer maxAge) {
        QUser user = QUser.user;
        BooleanExpression predicate = user.isNotNull(); // 初始条件
        if (name != null) {
            predicate = predicate.and(user.name.eq(name));
        }
        if (minAge != null && maxAge != null) {
            predicate = predicate.and(user.age.between(minAge, maxAge));
        }
        return (List) userRepository.findAll(predicate);
    }
}

总结

  • 简单动态查询:使用 @Query 注解和 SpEL 表达式。
  • 灵活动态查询:结合 MongoTemplate 或自定义 Repository 实现。
  • 强大动态查询:使用 Querydsl 实现复杂的动态查询。

根据项目需求选择合适的方式,MongoTemplate 和 Querydsl 提供了更高的灵活性,适合复杂的查询场景。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表