Spring-data-mongodb拦截查询和注入谓词或规范

时间:2016-05-23 17:02:00

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

环境:

spring-data-mongo:3.2.2 mongo-java-driver:@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);

}

存储库:

Page<Product> findAll(Pageable page);

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

(...)

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

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

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);
    }
}

避免这样做

 <form>

  <input class="target" type="text" value="Field 1">

  <select class="target">

    <option value="option1" selected="selected">Option 1</option>

    <option value="option2">Option 2</option>

  </select>

</form>


$( ".target" ).change(function() {

  alert( "Handler for .change() called." );

});

1 个答案:

答案 0 :(得分:0)

方面应该做到这一点。

@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);
  }

我会建议反对它,因为它为您的代码引入了一些魔力,操纵查询不应该是方面的关注。 您希望避免在存储库中使用多个查找方法的原因是什么?