Cara menggunakan OrderBy dengan findAll di Data Musim Semi


288

Saya menggunakan data pegas dan DAO saya terlihat seperti

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

Pada kode di atas, baris komentar menunjukkan maksud saya. Bisakah pegas Data menyediakan fungsionalitas bawaan untuk menggunakan metode seperti itu untuk menemukan semua catatan pesanan oleh beberapa kolom dengan ASC / DESC?

Jawaban:


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

Kode di atas seharusnya berfungsi. Saya menggunakan sesuatu yang serupa:

public List<Pilot> findTop10ByOrderByLevelDesc();

Ini mengembalikan 10 baris dengan level tertinggi.

PENTING: Karena saya telah diberitahu bahwa mudah untuk melewatkan poin kunci dari jawaban ini, inilah sedikit klarifikasi:

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

4
Untuk metode tanda tangan Anda bekerja sebagaimana dimaksud dengan Spring data JPA, Anda harus mencakup "semua" kata kunci, seperti: List<StudentEntity> findAllByOrderByIdAsc();. Menambahkan jenis kembali dan menghapus pengubah publik yang berlebihan juga merupakan ide bagus;)
Håvard Geithus

1
Saya setuju bahwa publik itu mubazir tetapi itu membuat semuanya menjadi jelas kalau-kalau ada orang lain yang bekerja pada kode Anda. Anda tidak pernah tahu siapa itu: PI tidak mengubah apa pun selain nama metode dalam kode penulis karena itu bukan di mana masalahnya dan jika seseorang tidak tahu apa yang seharusnya ada, mudah-mudahan mereka akan belajar sesuatu yang baru. Selain itu, ada dalam contoh saya di bawah ini sehingga mereka tidak perlu mencari tuhan yang tahu di mana, tetapi jika Anda bersikeras, maka jadilah :) Ditambahkan kata kunci 'semua'. Terima kasih.
Sikor

73
Perhatikan bahwa sedikit Bysebelum OrderBykata kunci membuat semua perbedaan.
Stefan Haberl

5
Masih tidak mengerti mengapa perlu menambahkan ekstra Bydi depan OrderBy. The dokumentasi tidak memberitahu tentang hal itu .
Xtreme Biker

3
@XtremeBiker Dari tautan dokumentasi yang Anda berikan: "Namun, By pertama berfungsi sebagai pembatas untuk menunjukkan awal kriteria aktual." Selain itu, jika Anda gulir ke bawah ke bagian "3.4.5. Membatasi hasil kueri", sebenarnya ada contoh seperti ini, tetapi tidak dijelaskan.
Sikor

54

AFAIK, saya tidak berpikir ini mungkin dengan kueri penamaan metode langsung. Namun Anda dapat menggunakan mekanisme penyortiran bawaan, menggunakan Sortkelas. Repositori memiliki findAll(Sort)metode yang dapat Anda gunakan untuk instance Sort. Sebagai contoh:

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

Ini memang mungkin menggunakan findAllByOrderByIdAsc () seperti yang disebutkan dalam jawaban Sikor di bawah ini ... @Pashash yang benar-benar harus menjadi jawaban yang benar
Samuel Parsonage

Cara alternatif melakukan semacam itu di tingkat layanan jika Anda ingin menjaga repositori Anda tidak berantakan. Perlu diingat ukuran hasilnya!
dkanejs

2
Metode findAll()dalam tipe CrudRepository<>ini tidak berlaku untuk argumen (Sort)
Thiago Pereira

5
@ThiagoPereira Anda harus memperluas JpaRepository<>jika Anda ingin menggunakan contoh di atas.
Waleed Abdalmajeed

15

Silakan lihat di Spring Data JPA - Documentation Referensi, bagian 5.3. Metode Pertanyaan , terutama pada bagian 5.3.2. Pembuatan Kueri , di " Tabel 3. Kata kunci yang didukung di dalam nama metode " (tautan pada 2019-05-03).

Saya pikir itu persis apa yang Anda butuhkan dan permintaan yang sama seperti yang Anda nyatakan harus bekerja ...


1
Tautan Anda tidak berfungsi -> Saya berasumsi bahwa Anda ingin menunjukkan tautan ini: docs.spring.io/spring-data/jpa/docs/current/reference/html/…
Jørgen Skår Fischer


3

Ya, Anda dapat mengurutkan menggunakan metode kueri di Data Musim Semi.

Mis: pesanan naik atau turun dengan menggunakan nilai bidang id.

Kode:

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

solusi alternatif:

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

Penyortiran Data Musim Semi: Penyortiran


3

Saya mencoba dalam contoh ini untuk menunjukkan kepada Anda contoh lengkap untuk mempersonalisasi jenis OrderBy Anda

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

Anda akan menggunakan contoh ini: Metode untuk membangun secara dinamis objek yang disortir dari 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

Menggabungkan semua jawaban di atas, Anda dapat menulis kode yang dapat digunakan kembali dengan 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();
  }
}

Objek DAO overload menemukan metode - pada dasarnya, masih menggunakan findAll()

public interface StudentDAO extends CrudRepository<StudentEntity, Long> {

  Iterable<StudentEntity> findAll(Sort sort);

}

StudentEntitymemanjang BaseEntityyang berisi bidang berulang (mungkin Anda juga ingin mengurutkan berdasarkan ID)

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

  String firstName;
  String surname;

}

Akhirnya, layanan dan penggunaan SORT_BY_CREATED_AT_DESCyang mungkin akan digunakan tidak hanya di Internet StudentService.

@Service
class StudentService {

  @Autowired
  StudentDAO studentDao;

  Iterable<StudentEntity> findStudents() {
    return this.studentDao.findAll(SORT_BY_CREATED_AT_DESC);
  }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.