Я использую приложение для весенней загрузки, и существуют следующие 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);
где pageable
- это экземпляр org.springframework.data.domain.Pageable
.
Я могу сортировать, используя другие столбцы в Person
. Но я хочу отсортировать на основе набора адресов, основываясь на количестве записей Address
для каждого объекта Person
.
Короче хотел отсортировать Лица на основе размера коллекции Collection. Порядок сортировки (ASC или DESC) поступает от внешнего интерфейса.
Есть идеи, как должен выглядеть объект Pageable
для реализации этого? Также без возврата дубликатов записи Person
, если для Address
существует более одного Person
.
Вот решение по Порядок по количеству с использованием Spring Data JpaRepository.
В своем эксперименте я попытался определить репозиторий следующим образом, но с этим возникла проблема; поскольку мы определяем запрос на PersonRepository
для сортировки на основе данных spring addressCount, просматривает 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);
}
В качестве обходного пути я попытался перенести логику сортировки в само определение запроса, и в итоге я получил 2 версии для режимов ASC и DESC:
@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 дана
Spring Data JPa имеет много очень эффективных функций, но не всемогущ. Вам необходимо создать уникальный запрос ... или спецификацию, потому что вы можете использовать его вместе с Pageable.