Как использовать OrderBy с findAll в Spring Data

291

Я использую данные весны, и мой DAO выглядит

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

В приведенном выше коде строка комментариев показывает мое намерение. Может ли Spring Data предоставить встроенную функциональность для использования такого метода, чтобы найти все записи по некоторому столбцу с ASC / DESC?

Прашант Шилимкар
источник

Ответы:

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

Код выше должен работать. Я использую нечто подобное:

public List<Pilot> findTop10ByOrderByLevelDesc();

Возвращает 10 строк с самым высоким уровнем.

ВАЖНО: Поскольку мне сказали, что легко пропустить ключевой момент этого ответа, вот небольшое пояснение:

findAllByOrderByIdAsc(); // don't miss "by"
       ^
Sikor
источник
4
Для вашего метода подписи к работе по назначению с Spring Data JPA, вы должны включать в себя «все» ключевое слово, например так: List<StudentEntity> findAllByOrderByIdAsc();. Добавление типа возврата и удаление избыточного публичного модификатора также является хорошей идеей;)
Håvard Geithus
1
Я согласен с тем, что public является избыточным, но он все проясняет на случай, если кто-то еще будет работать над вашим кодом. Вы никогда не знаете, кто это будет: PI не изменил ничего, кроме имени метода в коде авторов, потому что проблема не в этом, и если кто-то не знает, что должно быть, надеюсь, они узнают что-то новое. Кроме того, это в моем примере ниже, чтобы им не пришлось искать бог знает где, но если вы настаиваете, пусть будет так :) Добавлено ключевое слово «все». Спасибо.
Сикор
74
Обратите внимание, что немного Byперед OrderByключевым словом имеет все значение.
Стефан Хаберл
5
До сих пор не понимаю, почему необходимо добавить дополнительные Byперед OrderBy. Документация не говорит об этом .
экстремальный байкер
3
@XtremeBiker Из ссылки на документацию, которую вы предоставили: «Тем не менее, первый By действует как разделитель, чтобы указать начало фактических критериев». Более того, если вы прокрутите вниз до раздела «3.4.5. Ограничение результатов запроса», на самом деле есть такой пример, но он не объясняется.
Sikor
55

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

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

Я думаю, что это именно то, что вам нужно, и тот же запрос, как вы заявили, должен работать ...

shlomi33
источник
1
Ваша ссылка не работает -> Я предполагаю, что вы хотели указать на эту ссылку: docs.spring.io/spring-data/jpa/docs/current/reference/html/…
Йорген Скор Фишер
6

Простой способ:

repository.findAll(Sort.by(Sort.Direction.DESC, "colName"));

Источник: https://www.baeldung.com/spring-data-sorting.

TizonDife Villiard
источник
Есть 2 одинаковых ответа. И ваш ответ имел неправильную форму
Дред
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);

}

StudentEntityextends, BaseEntityкоторый содержит повторяемые поля (возможно, вы также хотите отсортировать по ID)

@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);
  }
}
J.Wincewicz
источник