【问题标题】:Spring-data-mongodb intercept query and inject predicate or specificationspring-data-mongodb 拦截查询并注入谓词或规范
【发布时间】:2016-09-20 16:02:23
【问题描述】:

环境:

spring-data-mongo: 1.7.0.RC1 mongo-java-driver:3.2.2

文档:

@Document(collection = "products")
public class Product  {

    @Id
    private String sid;

    private String name;

    private Long vendor;

    (...)
}

存储库:

public interface ProductRepository extends MongoRepository<Product, String> {

    Product findByName(String productName);

}

我的目标是拦截对 Product 集合执行的任何查询并添加谓词或规范,而无需修改存储库或实现方法 findByNameAndBelongsToVendorList。

我需要这个拦截器或 aspectJ,因为我有多种方法,例如:

Page<Product> findAll(Pageable page);

List<Product> findByCategory(String category, Pageable pageRequest);

(...)

目标

findByName // perform a filter by name (explicit) 
           // and a filter by vendor (injected via inteceptor or aspecJ)

避免这样做

@Repository
public class ProductRepositoryCustomImpl implements ProductRepositoryCustom {

    @Autowired
    private MongoTemplate template;

    public Product findByNameAndBelongsToVendorList(String name, List<Long> vendors, Pageable pageRequest) {

        Criteria criteriaVendor = Criteria.where("vendors").in(vendors);
        Query query = new Query(criteriaVendor);
        query.with(pageRequest);

        return template.findOne(query, Product.class);
    }
}

【问题讨论】:

    标签: java spring mongodb spring-data spring-data-mongodb


    【解决方案1】:

    方面应该可以解决问题。

    @Aspect
    public class YourAspect {
    
      @Autowired
      private MongoTemplate template;
    
      @Pointcut("execution(public * findByName(..))")
        private void findByName() {
      }
    
      @Pointcut("within(com.leonel.repository.ProductRepository)")
      private void repository() {
      }
    
      @Around("repository() && findByName()")
      public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
          Object[] args = pjp.getArgs();
          String name = (String) args[0];
    
          Criteria newCriteria = YOUR NEW LOGIC HERE;
          Query query = new Query(newCriteria);
    
          return template.find(query, Your.class);
      }
    

    我建议不要这样做,因为它给您的代码带来了一些魔力,并且操作查询不应该是方面的问题。 您希望避免在存储库中使用多个 find 方法的原因是什么?

    【讨论】:

    • 目前我使用 2 个框架 ... SpringData e MongoTemplate。使用 MongoTemplate,我可以在 org.springframework.data.mongodb.core 上使用切入点并拦截 findAll、findOne 等所有方法……但使用 SpringData 我还不知道该怎么做。
    猜你喜欢
    • 2014-08-04
    • 2017-10-04
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-28
    相关资源
    最近更新 更多