如何接受 JPA 排序值的 @OrderBy 作为动态参数?

How to accept @OrderBy of JPA sort value as a dynamic parameter?

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

假设我有一个实体 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(Specification specification,Pageable page)

调用 A 的存储库

从 UI 开始,使用排序参数调用 rest 控制器,如下模式

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

由于是嵌套集合,上述排序无效。 可排序字段为日期字段、数量。

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

调用存储库上的全部查找时如何实现此目的?

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

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

你不能这样做,仅使用 Spring 数据是不可能的。

从概念上讲,您正在使用 JpaSpecificationExecutorSpecifications 参数化 class A.

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

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

即使在 ASpecification 正文中,您使用某种涉及必须排序的集合的子查询,并且您按集合的字段建立排序在这个子查询中,我认为 - 也许应该测试 - JPA 提供者将 return class A 的实例,然后根据提供的 @OrderBy 初始化集合标准。

顺便说一下,在语义上,使用 @OrderBy 时使用 List 而不是 Set 始终是一个好习惯。

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

学习本教程:REST Query Language with Spring Data JPA and Querydsl

当你使用

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

}