【问题标题】:Spring data jpa sort by nested object collection sizeSpring data jpa按嵌套对象集合大小排序
【发布时间】:2018-09-13 08:53:06
【问题描述】:

我正在使用 Spring Boot 应用程序,并且存在以下 2 个实体。

Person.java

@Entity
@Data
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "PERSON")
public class Person extends BaseEntity {
    @NotNull
    @Enumerated(EnumType.STRING)
    private StatusType status;

    @JsonIgnore
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(
            name = "PERSON_ADDRESS",
            joinColumns = @JoinColumn(
                    name = "person_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(
                    name = "address_id", referencedColumnName = "id"))
    private Collection<Info> addresses;
}

Address.java

@Entity
@Data
@EqualsAndHashCode(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "ADDRESS")
public class Address extends BaseEntity {
    @NotNull
    private String address;

    @ManyToMany(mappedBy = "addresses")
    private Collection<Person> persons;
}

我正在使用JpaRepository,如下所示。

@Repository
public interface PersonRepository extends JpaRepository<Person, Long> {
}

我使用下面的语句来实现分页和排序。

Page<Person> allPersons = personRepository.findAll(pageable);

其中pageableorg.springframework.data.domain.Pageable 的一个实例。

我可以使用Person 中的其他列进行排序。但我想根据地址集合进行排序,基于每个Person 实体的Address 记录数。

简而言之,我想根据 Collection 的集合大小对 Persons 进行排序。排序顺序(ASC 或 DESC)来自前端。

知道Pageable 对象应该如何实现这个吗?如果Person 存在多个Address,也不会返回任何重复的Person 记录。

【问题讨论】:

  • Spring Data JPa 有很多非常有效的特性,但并不是万能的。您必须创建一个唯一的查询...或规范,因为您可以将它与 Pageable 一起使用。

标签: java spring spring-boot spring-data-jpa


【解决方案1】:

这里是根据Order by count using Spring Data JpaRepository的解决方案。

在我的实验中,我尝试将 Repository 定义如下,但存在问题;因为我们在 PersonRepository 上定义查询,以便根据 addressCount 进行排序,所以 spring 数据会查看 Person。

@Repository
public interface PersonRepository extends JpaRepository<Person, Long> {

    @Query(
        value = "select p from Person p join p.addresses ad group by p",
        countQuery = "select count(p) from Person p"
    )
    Page <Person> findAllWithAddressCount(Pageable pageable);
}

因此,作为一种解决方法,我尝试将排序逻辑转换为查询定义本身,最终得到了 ASC 和 DESC 模式的 2 个版本:

@Repository
public interface PersonRepository extends JpaRepository <Person, Long> {

    @Query(
        value = "select p from Person p join p.addresses ad group by p Order By addressCount asc",
        countQuery = "select count(p) from Person p"
    )
    Page<Person> findAllOrderByAddressCountAsc(Pageable pageable);

    @Query(
        value = "select p from Person p join p.addresses ad group by p Order By addressCount desc",
        countQuery = "select count(p) from Person p"
    )
    Page<Person> findAllOrderByAddressCountDesc(Pageable pageable);
}

希望这会有所帮助。

【讨论】:

  • Pageable 对象排序字段是什么样的?
  • 另外,如果只有 6 个人,其中 3 个人有 2 个地址,其余的人各有一个地址,那么如果我们使用这个 countQuery,我会得到 9 个人记录对吗?其中 3 个重复
  • @PhilipJohni 我对它进行了试验并更改了我提出的解决方案,请检查
  • 嗯,我在另一个 stackoverflow 帖子中看到了这个解决方案,想知道是否有其他方法。也许您还可以添加原始答案的链接作为您的答案的参考。
  • @PhilipJohn 参考给出
猜你喜欢
  • 2013-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-08
相关资源
最近更新 更多