Як користуватися OrderBy з findAll у Spring Data


288

Я використовую весняні дані, і такий DAO виглядає так

public interface StudentDAO extends JpaRepository<StudentEntity, Integer> {
    public findAllOrderByIdAsc();   // I want to use some thing like this
}

У наведеному вище коді коментований рядок показує мій намір. Чи можуть Spring Data надавати вбудовану функціональність для використання такого методу для пошуку всіх порядків записів у якомусь стовпці з ASC / DESC?

Відповіді:


657
public interface StudentDAO extends JpaRepository<StudentEntity, Integer> {
    public List<StudentEntity> findAllByOrderByIdAsc();
}

Код вище повинен працювати. Я використовую щось подібне:

public List<Pilot> findTop10ByOrderByLevelDesc();

Він повертає 10 рядів з найвищим рівнем.

ВАЖЛИВО: Оскільки мені сказали, що легко пропустити ключовий момент цієї відповіді, ось невелике уточнення:

findAllByOrderByIdAsc(); // don't miss "by"
       ^

4
Для вашого методу підпису до роботи за призначенням з Spring Data JPA, ви повинні включати в себе «все» ключове слово, наприклад так: List<StudentEntity> findAllByOrderByIdAsc();. Додавання типу повернення та видалення надлишкового публічного модифікатора також є хорошою ідеєю;)
Håvard Geithus

1
Я погоджуюся з тим, що публіка є зайвою, але це чітко пояснює, якщо хтось інший повинен працювати над вашим кодом. Ніколи не знаєш, хто це буде: PI не змінив нічого іншого, крім назви методу в коді авторів, тому що там не проблема, і якщо хтось не знає, що там має бути, сподіваємось, вони дізнаються щось нове. Крім того, це в моєму прикладі нижче, тому їм не доведеться шукати бог знає куди, але якщо ви наполягаєте, то так і буде :) Додано ключове слово "все". Дякую.
Сікор

73
Зауважте, що ключове слово трохи Byраніше, ніж OrderByусе, має значення.
Стефан Хаберль

5
Досі не розумію, чому потрібно додати додатковий Byна передній частині OrderBy. Документація не говорить про це .
Xtreme Biker

3
@XtremeBiker З посилання на документацію ви надали: "Однак, перший By виступає в якості роздільника, щоб вказати початок фактичних критеріїв". Крім того, якщо прокрутити вниз до розділу "3.4.5. Обмеження результатів запитів", насправді є такий приклад, але він не пояснюється.
Сікор

54

AFAIK, я не думаю, що це можливо завдяки прямому методу іменування запиту. Однак ви можете використовувати вбудований механізм сортування за допомогою Sortкласу. У сховищі є findAll(Sort)метод, до якого можна передати екземпляр Sort. Наприклад:

import org.springframework.data.domain.Sort;

@Repository
public class StudentServiceImpl implements StudentService {
    @Autowired
    private StudentDAO studentDao;

    @Override
    public List<Student> findAll() {
        return studentDao.findAll(sortByIdAsc());
    }

    private Sort sortByIdAsc() {
        return new Sort(Sort.Direction.ASC, "id");
    }
} 

Це дійсно можливо, використовуючи findAllByOrderByIdAsc (), як згадується у відповіді Сікора нижче ... @Prashant, що справді має бути правильною відповіддю
Самуель Парсонаж

Альтернативний спосіб зробити сортування в рівні обслуговування, якщо ви хочете, щоб ваші сховища були менш захаращеними. Майте на увазі розмір результату!
dkanejs

2
Метод findAll()у типі CrudRepository<>не застосовується для аргументів (Сортування)
Тіаго Перейра

5
@ThiagoPereira вам слід поширити, JpaRepository<>якщо ви бажаєте скористатись вищевказаним прикладом.
Уелід Абдалмайєд

15

Будь ласка, подивіться на весняний спільний доступ до даних JPA - Довідкова документація, розділ 5.3. Методи запитів , особливо в розділі 5.3.2. Створення запиту в " Таблиці 3. Підтримувані ключові слова всередині імен методів " (посилання станом на 2019-05-03).

Я думаю, він має саме те, що вам потрібно, і такий же запит, як ви заявили, повинен працювати ...


1
Ваше посилання не працює -> Я припускаю, що ви хотіли вказати на це посилання: docs.spring.io/spring-data/jpa/docs/current/reference/html/…
Jørgen Skår Fischer


3

Так, ви можете сортувати, використовуючи метод запиту у Spring Data.

Наприклад: порядок зростання або низхідний порядок, використовуючи значення поля id.

Код:

  public interface StudentDAO extends JpaRepository<StudentEntity, Integer> {
    public findAllByOrderByIdAsc();   
}

альтернативне рішення:

    @Repository
public class StudentServiceImpl implements StudentService {
    @Autowired
    private StudentDAO studentDao;

    @Override
    public List<Student> findAll() {
        return studentDao.findAll(orderByIdAsc());
    }
private Sort orderByIdAsc() {
    return new Sort(Sort.Direction.ASC, "id")
                .and(new Sort(Sort.Direction.ASC, "name"));
}
}

Весняне сортування даних: сортування


3

Я намагаюся в цьому прикладі показати вам повний приклад для персоналізації ваших сортів OrderBy

 import java.util.List;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.jpa.repository.*;
 import org.springframework.data.repository.query.Param;
 import org.springframework.stereotype.Repository;
 import org.springframework.data.domain.Sort;
 /**
 * Spring Data  repository for the User entity.
 */
 @SuppressWarnings("unused")
 @Repository
 public interface UserRepository extends JpaRepository<User, Long> {
 List <User> findAllWithCustomOrderBy(Sort sort);
 }

ви будете використовувати цей приклад: Метод для динамічного побудови об'єкта, який містить екземпляр Sort:

import org.springframework.data.domain.Sort;
public class SampleOrderBySpring{
 Sort dynamicOrderBySort = createSort();
     public static void main( String[] args )
     {
       System.out.println("default sort \"firstName\",\"name\",\"age\",\"size\" ");
       Sort defaultSort = createStaticSort();
       System.out.println(userRepository.findAllWithCustomOrderBy(defaultSort ));


       String[] orderBySortedArray = {"name", "firstName"};
       System.out.println("default sort ,\"name\",\"firstName\" ");
       Sort dynamicSort = createDynamicSort(orderBySortedArray );
       System.out.println(userRepository.findAllWithCustomOrderBy(dynamicSort ));
      }
      public Sort createDynamicSort(String[] arrayOrdre) {
        return  Sort.by(arrayOrdre);
        }

   public Sort createStaticSort() {
        String[] arrayOrdre  ={"firstName","name","age","size");
        return  Sort.by(arrayOrdre);
        }
}

0

Поєднавши всі відповіді вище, ви можете написати код багаторазового використання з BaseEntity:

@Data
@NoArgsConstructor
@MappedSuperclass
public abstract class BaseEntity {

  @Transient
  public static final Sort SORT_BY_CREATED_AT_DESC = 
                        Sort.by(Sort.Direction.DESC, "createdAt");

  @Id
  private Long id;
  private LocalDateTime createdAt;
  private LocalDateTime updatedAt;

  @PrePersist
  void prePersist() {
    this.createdAt = LocalDateTime.now();
  }

  @PreUpdate
  void preUpdate() {
    this.updatedAt = LocalDateTime.now();
  }
}

Об'єкт DAO перевантажує метод findAll - в основному, все ще використовується findAll()

public interface StudentDAO extends CrudRepository<StudentEntity, Long> {

  Iterable<StudentEntity> findAll(Sort sort);

}

StudentEntityрозширення, BaseEntityщо містить поля, що повторюються (можливо, ви також хочете сортувати за ідентифікатором)

@Getter
@Setter
@FieldDefaults(level = AccessLevel.PRIVATE)
@Entity
class StudentEntity extends BaseEntity {

  String firstName;
  String surname;

}

Нарешті, послуга та використання SORT_BY_CREATED_AT_DESCяких, ймовірно, будуть використовуватися не лише в StudentService.

@Service
class StudentService {

  @Autowired
  StudentDAO studentDao;

  Iterable<StudentEntity> findStudents() {
    return this.studentDao.findAll(SORT_BY_CREATED_AT_DESC);
  }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.