1

我想根据查询参数排序对嵌套集合属性进行动态排序。

假设我有一个实体 A

class A{

@OneToMany(mappedBy="a")
private Set<B> bset;

}

class B{

private LocalDate datefield;
@ManyToOne
private C c;

}

class C
{
private Double quantity;

}

我正在使用 findAll(规范规范,可分页页面)调用A的存储库

从 UI 中,使用排序参数调用休息控制器,如下所示

 url?page=0&size=10&sort=bset_datefield

由于它是嵌套集合,因此上述排序不起作用。可排序的字段是日期字段、数量。

我知道@OrderBy("bset.datefield")会起作用,但参数应该是动态的。

调用 find All on A repository 时如何实现这一点?

4

3 回答 3

0

它无法完成,因为在初始化 entityManager 时会评估注释。

最好的选择是,创建一个有序的查询,或者如果从现在开始使用 Java 8,则在获得列表后,使用流的排序方法进行排序。

于 2020-07-24T15:37:29.037 回答
0

您不能这样做,仅使用 Spring Data 是不可能的。

从概念上讲,您使用的是根据类 A 参数化的aJpaSpecificationExecutor和s。Specification

在指定的findAll方法中,您可以A按任何属性排序,甚至可以按嵌套属性排序,但您正在排序A

您可以指示 JPA 提供程序对fetch集合进行排序,以按集合字段排序,但不能对集合本身进行排序。

即使在您的Specification正文中A使用某种涉及必须排序的集合的子查询,并且您在此子查询中通过集合的字段建立排序,我认为 - 也许应该对其进行测试 - JPA 提供者将返回类的实例,A然后根据提供的@OrderBy标准初始化集合。

顺便说一句,从语义上讲,在使用时使用 aList而不是 a始终是一个好习惯。Set@OrderBy

因此,如果您想对集合进行排序,我认为您唯一的选择是处理在查询字符串中接收到的排序条件,并在将数据返回给客户端之前通过对象比较在内存中对集合进行排序。

于 2020-07-24T21:49:11.773 回答
0

遵循本教程:使用 Spring Data JPA 和 Querydsl 的 REST 查询语言

当你使用

MyUserPredicatesBuilder

它做了魔术。

@Controller
public class UserController {

@Autowired
private MyUserRepository myUserRepository;

@RequestMapping(method = RequestMethod.GET, value = "/myusers")
@ResponseBody
public Iterable<MyUser> search(@RequestParam(value = "search") String search) {
    MyUserPredicatesBuilder builder = new MyUserPredicatesBuilder();

    if (search != null) {
        Pattern pattern = Pattern.compile("(\w+?)(:|<|>)(\w+?),");
        Matcher matcher = pattern.matcher(search + ",");
        while (matcher.find()) {
            builder.with(matcher.group(1), matcher.group(2), matcher.group(3));
        }
    }
    BooleanExpression exp = builder.build();
    return myUserRepository.findAll(exp);
}

}

于 2021-06-22T21:25:20.470 回答