วิธีใช้ 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 สามารถใช้ฟังก์ชั่น inbuilt เพื่อใช้วิธีการดังกล่าวเพื่อค้นหาระเบียนทั้งหมดในบางคอลัมน์ด้วย 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
สำหรับลายเซ็นวิธีการของคุณในการทำงานตามที่ตั้งใจไว้กับฤดูใบไม้ผลิข้อมูล JPA คุณควรรวมถึง "ทุกคน" List<StudentEntity> findAllByOrderByIdAsc();คำหลักเช่นดังนั้น: การเพิ่มประเภทการส่งคืนและการลบตัวดัดแปลงสาธารณะที่ซ้ำซ้อนก็เป็นความคิดที่ดีเช่นกัน)
Håvard Geithus

1
ฉันยอมรับว่าสาธารณะซ้ำซ้อน แต่มันทำให้สิ่งต่าง ๆ ชัดเจนในกรณีที่คนอื่นต้องทำงานกับรหัสของคุณ คุณไม่มีทางรู้ว่าใครจะเป็น: PI ไม่ได้เปลี่ยนอะไรเลยนอกจากชื่อวิธีการในรหัสผู้เขียนเพราะมันไม่ใช่ปัญหาที่เกิดขึ้นและถ้ามีคนไม่ทราบว่าควรจะมีอะไรหวังว่าพวกเขาจะเรียนรู้สิ่งใหม่ นอกจากนี้ในตัวอย่างของฉันด้านล่างพวกเขาไม่ต้องค้นหาพระเจ้ารู้ว่าที่ไหน แต่ถ้าคุณยืนยันดังนั้นไม่ว่าจะเป็น :) เพิ่มคำหลัก 'ทั้งหมด' ขอบคุณ
Sikor

73
โปรดทราบว่าเล็กน้อยByก่อนOrderByคำหลักสร้างความแตกต่างทั้งหมด
Stefan Haberl

5
ยังคงไม่เข้าใจว่าทำไมมันเป็นสิ่งจำเป็นที่จะเพิ่มพิเศษในด้านหน้าของBy เอกสารไม่ได้บอกเกี่ยวกับเรื่องนี้ OrderBy
Xtreme Biker

3
@XtremeBiker จากลิงก์เอกสารที่คุณให้ไว้: "อย่างไรก็ตามตัวแรกโดยทำหน้าที่เป็นตัวคั่นเพื่อระบุจุดเริ่มต้นของเกณฑ์จริง" ยิ่งไปกว่านั้นถ้าคุณเลื่อนลงไปที่ส่วน "3.4.5 การ จำกัด ผลลัพธ์คิวรี" มีตัวอย่างเช่นนี้จริง ๆ แต่ไม่มีการอธิบาย
Sikor

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 () ที่กล่าวไว้ในคำตอบ Sikor ด้านล่าง ... @Prashant ที่จริงควรจะเป็นคำตอบที่ถูกต้อง
ซามูเอลกุฏิ

ทางเลือกอื่นในการจัดเรียงในระดับบริการถ้าคุณต้องการให้ที่เก็บของคุณยุ่งเหยิงน้อยลง โปรดจำไว้ว่าขนาดของผลที่ได้!
dkanejs

2
วิธีการfindAll()ในประเภทCrudRepository<>นี้ไม่สามารถใช้ได้กับข้อโต้แย้ง (เรียงลำดับ)
Thiago Pereira

5
@ThiagoPereira คุณควรขยายJpaRepository<>หากคุณต้องการใช้ตัวอย่างด้านบน
Waleed Abdalmajeed

15

โปรดดูที่Spring Data JPA - เอกสารอ้างอิงส่วน 5.3 วิธีการสืบค้นโดยเฉพาะในหัวข้อ5.3.2 การสร้างแบบสอบถามใน " ตารางที่ 3 คำหลักที่สนับสนุนภายในชื่อเมธอด " (ลิงก์ตั้งแต่ 2019-05-03)

ฉันคิดว่ามันมีสิ่งที่คุณต้องการและแบบสอบถามเดียวกันกับที่คุณระบุควรจะทำงาน ...


1
ลิงก์ของคุณใช้งานไม่ได้ -> ฉันถือว่าคุณต้องการชี้ไปที่ลิงก์นี้: docs.spring.io/spring-data/jpa/docs/current/reference/html/…
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"));
}
}

Spring Data Sorting: Sorting


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

คุณจะใช้ตัวอย่างนี้: วิธีการสร้างวัตถุที่อินสแตนซ์ของการเรียงลำดับแบบไดนามิก:

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 overloads วิธี findAll - โดยทั่วไปยังคงใช้ findAll()

public interface StudentDAO extends CrudRepository<StudentEntity, Long> {

  Iterable<StudentEntity> findAll(Sort sort);

}

StudentEntityขยาย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);
  }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.