Cách sử dụng OrderBy với find ALL trong Spring Data


288

Tôi đang sử dụng dữ liệu mùa xuân và DAO của tôi trông giống như

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

Trong mã trên, dòng nhận xét cho thấy ý định của tôi. Dữ liệu mùa xuân có thể cung cấp chức năng sẵn có để sử dụng một phương pháp như vậy để tìm tất cả các thứ tự hồ sơ theo một số cột với ASC / DESC không?

Câu trả lời:


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

Các mã ở trên nên hoạt động. Tôi đang sử dụng một cái gì đó tương tự:

public List<Pilot> findTop10ByOrderByLevelDesc();

Nó trả về 10 hàng với mức cao nhất.

QUAN TRỌNG: Vì tôi đã được thông báo rằng thật dễ dàng bỏ lỡ điểm chính của câu trả lời này, đây là một chút làm rõ:

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

4
Để chữ ký phương thức của bạn hoạt động như dự định với Spring Data JPA, bạn nên bao gồm từ khóa "tất cả", như vậy : List<StudentEntity> findAllByOrderByIdAsc();. Thêm một kiểu trả về và loại bỏ công cụ sửa đổi công khai dự phòng cũng là một ý tưởng hay;)
Håvard Geithus

1
Tôi đồng ý rằng công khai là dư thừa nhưng nó giúp mọi thứ rõ ràng trong trường hợp người khác phải làm việc với mã của bạn. Bạn không bao giờ biết ai sẽ là ai: PI không thay đổi gì khác ngoài tên phương thức trong mã tác giả bởi vì đó không phải là vấn đề và nếu ai đó không biết nên làm gì ở đó, hy vọng họ sẽ học được điều gì đó mới. Bên cạnh đó, đó là ví dụ của tôi dưới đây để họ không phải tìm kiếm thần biết ở đâu, nhưng nếu bạn khăng khăng, thì cứ thế :) Thêm từ khóa 'tất cả'. Cảm ơn.
Sikor

73
Lưu ý rằng một chút Bytrước khi OrderBytừ khóa làm cho tất cả sự khác biệt.
Stefan Haberl

5
Vẫn không hiểu tại sao cần phải thêm một phần phụ Byở phía trước OrderBy. Các tài liệu không nói về nó .
Xtreme Biker

3
@XtremeBiker Từ liên kết tài liệu bạn đã cung cấp: "Tuy nhiên, đầu tiên Bởi đóng vai trò là dấu phân cách để chỉ ra sự bắt đầu của các tiêu chí thực tế." Hơn nữa, nếu bạn cuộn xuống phần "3.4.5. Giới hạn kết quả truy vấn", thực sự có một ví dụ như thế này, nhưng nó không được giải thích.
Sikor

54

AFAIK, tôi không nghĩ rằng điều này là có thể với truy vấn đặt tên phương thức trực tiếp. Tuy nhiên, bạn có thể sử dụng cơ chế sắp xếp được xây dựng, sử dụng Sortlớp. Kho lưu trữ có một findAll(Sort)phương thức mà bạn có thể truyền một thể hiện của Sort. Ví dụ:

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

Điều này thực sự có thể sử dụng findAllByOrderByIdAsc () như được đề cập trong câu trả lời của Sikor bên dưới ... @Prashant thực sự phải là câu trả lời chính xác
Samuel Parsonage

Cách khác để thực hiện sắp xếp trong tầng dịch vụ nếu bạn muốn giữ cho kho lưu trữ của bạn ít lộn xộn hơn. Hãy ghi nhớ kích thước kết quả mặc dù!
dkanejs

2
Phương thức findAll()trong loại CrudRepository<>không áp dụng cho các đối số (Sắp xếp)
Thiago Pereira

5
@ThiagoPereira bạn nên gia hạn JpaRepository<>nếu bạn muốn sử dụng ví dụ trên.
Walmed Abdalmajeed

15

Xin hãy xem Spring Data JPA - Tài liệu tham khảo, phần 5.3. Phương thức truy vấn , đặc biệt là trong phần 5.3.2. Tạo truy vấn , trong " Bảng 3. Các từ khóa được hỗ trợ bên trong tên phương thức " (các liên kết kể từ 2019-05-03).

Tôi nghĩ rằng nó có chính xác những gì bạn cần và cùng một truy vấn như bạn đã nêu nên hoạt động ...


1
Liên kết của bạn không hoạt động -> Tôi giả sử bạn muốn trỏ đến liên kết này: docs.spring.io/spring-data/jpa/docs/civerse/reference/html/iêu
Jørgen Skår Fischer


3

Có, bạn có thể sắp xếp bằng phương thức truy vấn trong Spring Data.

Ví dụ: thứ tự tăng dần hoặc thứ tự giảm dần bằng cách sử dụng giá trị của trường id.

Mã số:

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

giải pháp thay thế:

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

Sắp xếp dữ liệu mùa xuân: Sắp xếp


3

Tôi cố gắng trong ví dụ này để cho bạn thấy một ví dụ hoàn chỉnh để cá nhân hóa các loại OrderBy của bạn

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

bạn sẽ sử dụng ví dụ này: Một phương thức để xây dựng động một đối tượng thể hiện của Sắp xếp:

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

Kết hợp tất cả các câu trả lời ở trên, bạn có thể viết mã có thể sử dụng lại với 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();
  }
}

Đối tượng DAO quá tải phương thức find ALL - về cơ bản, vẫn sử dụng findAll()

public interface StudentDAO extends CrudRepository<StudentEntity, Long> {

  Iterable<StudentEntity> findAll(Sort sort);

}

StudentEntitymở rộng BaseEntitycó chứa các trường lặp lại (có thể bạn cũng muốn sắp xếp theo ID)

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

  String firstName;
  String surname;

}

Cuối cùng, dịch vụ và cách sử dụng SORT_BY_CREATED_AT_DESCcó lẽ sẽ được sử dụng không chỉ trong StudentService.

@Service
class StudentService {

  @Autowired
  StudentDAO studentDao;

  Iterable<StudentEntity> findStudents() {
    return this.studentDao.findAll(SORT_BY_CREATED_AT_DESC);
  }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.