在具有许多属性的Spring Data JPA中过滤结果的最佳解决方案是什么?

时间:2014-10-19 10:06:09

标签: hibernate jpa repository spring-data-jpa querydsl

我在这里有一个产品表的案例,需要通过用户输入过滤,如类别,颜色,大小,价格范围等等。

我使用的是Spring Data JPA,并且对来自方法名称的派生查询感到满意,当我被迫使用@query选项来处理更复杂的查询时,例如连接和...

但对于我需要的Filter方法,我恐怕不得不写这样的东西

public interface ProductRepository extends JpaRepository<Product, Long> {
   //..... other methods

Page<Product> findByCategoriesContainingAndSalepriceBetween(List<Category> categories, Float minprice, Float maxprice, PageRequest pagerequest);

Page<Product> findByCategoriesContaining(List<Category> categories, PageRequest pagerequest);

Page<Product> findByCategoriesContainingAndSizeIn(List<Category> categories,Int[] sizes, PageRequest pagerequest);

Page<Product> findByCategoriesContainingAndSizeInAndSalepriceBetween(List<Category> categories,Float minprice, Float maxprice, PageRequest pagerequest);
     

}

似乎添加了一些其他字段会迫使我写出这么多不同的组合

所以我查看了QueryDsl和规范,但它们似乎有很多额外的代码,你能把我放在正确的道路上吗?

2 个答案:

答案 0 :(得分:4)

我不同意QueryDSL会产生大量额外代码。这是我对QueryDSL的一些测试代码:

存储库定义:

public interface UserRepository extends PagingAndSortingRepository<User, Long>, QueryDslPredicateExecutor<User> {

    public User findOne(Predicate predicate);

    public List<User> findAll(Predicate predicate);
}

基于各种属性及其组合的测试代码:

 @Test
    public void testFindByEmailAddress() {
        User user = repository.findOne(QUser.user.emailAddress.eq("jack@hamilton.net"));
        Assert.assertNotNull(user);
        Assert.assertEquals("Jack", user.getForename());
        Assert.assertEquals("Hamilton", user.getSurname());
    }

    @Test
    public void testFindByGender() {
        List<User> users = repository.findAll(QUser.user.gender.eq(Gender.M));
        Assert.assertEquals(4, users.size());

        users = repository.findAll(QUser.user.gender.eq(Gender.F));
        Assert.assertEquals(2, users.size());
    }

    @Test
    public void testFindByCity() {

        List<User> users = repository.findAll(QUser.user.address.town.eq("Edinburgh"));
        Assert.assertEquals(2, users.size());

        users = repository.findAll(QUser.user.address.town.eq("Stirling"));
        Assert.assertEquals(1, users.size());
    }

    @Test
    public void testFindByGenderAndCity() {
        List<User> users = repository.findAll(QUser.user.address.town.eq("Glasgow").and(QUser.user.gender.eq(Gender.M)));
        Assert.assertEquals(2, users.size());

        users = repository.findAll(QUser.user.address.town.eq("Glasgow").and(QUser.user.gender.eq(Gender.F)));
        Assert.assertEquals(1, users.size());
    }

答案 1 :(得分:0)

如果您使用的是 Java Spring 框架,则可以使用规范 API,它们提供了更高级别的连接抽象。您可以参考此线程中的答案。 Spring boot Dynamic Query