Spring Data JPA มีวิธีใดบ้างในการนับจำนวนรายการโดยใช้วิธีการแก้ไขชื่อ?


127

Spring Data JPAรองรับเอนทิตีการนับโดยใช้ข้อมูลจำเพาะ แต่มีวิธีใดบ้างในการนับเอนทิตีโดยใช้วิธีการแก้ไขชื่อ? สมมติว่าฉันต้องการวิธีcountByNameการนับเอนทิตีด้วยชื่อเฉพาะเช่นเดียวกับวิธีfindByNameการดึงเอนทิตีทั้งหมดที่มีชื่อเฉพาะ


6
โปรดยอมรับหนึ่งในคำตอบ YaoFeng ฉันได้ทดสอบ Spring Data JPA 1.5.2 แล้วและไวยากรณ์ countByName () ทำงานเป็นบันทึกย่อของ Abel
nullPainter

คำตอบ:


216

ในSpring Data 1.7.1 ปล่อยคุณสามารถทำได้ด้วยสองวิธีที่แตกต่างกัน

1) วิธีใหม่โดยใช้การสืบหาการสืบค้นสำหรับทั้งการนับและการลบแบบสอบถาม อ่านสิ่งนี้ (ตัวอย่างที่ 5) ตัวอย่าง,

public interface UserRepository extends CrudRepository<User, Integer> {
    Long countByName(String name);
}

2) วิธีเก่าโดยใช้คำอธิบายประกอบ @Query
ตัวอย่าง,

public interface UserRepository extends CrudRepository<User, Integer> {
    @Query("SELECT COUNT(u) FROM User u WHERE u.name=?1")
    Long aMethodNameOrSomething(String name);
}

หรือใช้คำอธิบายประกอบ @Param ด้วย

public interface UserRepository extends CrudRepository<User, Integer> {
    @Query("SELECT COUNT(u) FROM User u WHERE u.name=:name")
    Long aMethodNameOrSomething(@Param("name") String name);
}

ตรวจสอบคำตอบด้วย


3
แล้วฟังก์ชันการรวมอื่น ๆ เช่น sum, average ล่ะ?
lrkwz

คำถามเกี่ยวกับฟังก์ชันการนับไม่ใช่ผลรวมหรือค่าเฉลี่ย ข้อมูล Spring ยังไม่รองรับบางอย่างเช่น 'วิธีใหม่' สำหรับฟังก์ชันนี้ คุณสามารถใช้สิ่งนี้ได้
George Siggouroglou

1
ในตัวอย่างที่สองและสามของคุณฉันคิดว่าคุณจะต้องใช้ "SELECT COUNT (u) ... " เนื่องจากนี่ควรจะเป็นการสืบค้นแบบนับ
TheChrisPratt

ขอบคุณสำหรับความคิดเห็นของคุณ. มันเป็นความผิดพลาดของฉัน
George Siggouroglou

ไม่ต้องกังวลพบมัน - คอมมอน
ลัง

19

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

ตัวอย่าง:

@Query("select count(e) from Product e where e.area.code = ?1")
long countByAreaCode(String code);

3
โปรดทราบว่าวิธีนี้ควรส่งคืนlongแทนintมิฉะนั้นคุณจะได้รับ ClassCastException โดยไม่มีเบาะแสใด ๆ
Rangi Lin

13

JpaRepository ยังขยาย QueryByExampleExecutor คุณจึงไม่จำเป็นต้องกำหนดวิธีการที่กำหนดเองบนอินเทอร์เฟซของคุณด้วยซ้ำ:

public interface UserRepository extends JpaRepository<User, Long> {
    // no need of custom method
}

จากนั้นสอบถามเช่น:

User probe = new User();
u.setName = "John";
long count = repo.count(Example.of(probe));

เวอร์ชันนี้ฉันชอบมากที่สุด - โดยเฉพาะอย่างยิ่งเมื่อฉันไม่สามารถระบุได้ว่าควรทำงานอย่างไรตาม docu :-) คุณบันทึกวันของฉันไว้ :-) ตามข้อสังเกต: Primitives (เช่น int) รวมอยู่ในการค้นหา expamle เช่นint ageจะรวมแม้ว่าจะไม่ได้ตั้งค่าไว้ แต่Integer ageจะถูกแยกออกจากตัวอย่าง (อย่างน้อยก็ใน Eclipselink)
LeO

นี่คือสิ่งที่ฉันกำลังมองหา ขอบคุณ!
emrekgn


8

ตัวอย่างการทำงาน

@Repository
public interface TenantRepository extends JpaRepository< Tenant, Long > {
    List<Tenant>findByTenantName(String tenantName,Pageable pageRequest);
    long countByTenantName(String tenantName);
}

โทรจากชั้น DAO

@Override
public long countByTenantName(String tenantName) {
    return repository.countByTenantName(tenantName);
}

5

ตาม Abel หลังจากเวอร์ชัน 1.4 (ทดสอบในเวอร์ชัน 1.4.3.RELEASE) สามารถทำได้ด้วยวิธีนี้:

สาธารณะยาว countByName (ชื่อสตริง);



2

ขอบคุณทุกคน! ตอนนี้ก็ทำงานแล้ว DATAJPA-231

จะเป็นการดีถ้าสามารถสร้างจำนวน ... โดย ... วิธีการเช่นเดียวกับการค้นหา ... โดยคน ตัวอย่าง:

public interface UserRepository extends JpaRepository<User, Long> {

   public Long /*or BigInteger */ countByActiveTrue();
}


1

ฉันทำงานกับมันได้เพียงไม่กี่สัปดาห์ แต่ฉันไม่เชื่อว่าสิ่งนี้จะเป็นไปได้อย่างเคร่งครัดอย่างไรก็ตามคุณควรจะได้รับผลแบบเดียวกันนี้ด้วยความพยายามอีกเล็กน้อย เพียงแค่เขียนแบบสอบถามด้วยตัวคุณเองและใส่คำอธิบายประกอบชื่อวิธีการ อาจจะไม่ง่ายไปกว่าการเขียนวิธีการด้วยตัวเอง แต่มันสะอาดกว่าในความคิดของฉัน

แก้ไข: ขณะนี้เป็นไปได้ตามDATAJPA-231


0
@Autowired
private UserRepository userRepository;

@RequestMapping("/user/count")
private Long getNumberOfUsers(){
    return userRepository.count();
}

1
ตัวอย่างนี้ไม่อยู่ในหัวข้อ ผู้ใช้ถามว่าจะ countBy ชื่อฟิลด์อย่างไรและไม่เรียกการนับพื้นฐานจากบริการ REST อย่างไร
จาดบี

0

หากใครต้องการรับการนับโดยอิงตามเงื่อนไขต่างๆมากกว่าที่นี่คือตัวอย่างแบบสอบถามที่กำหนดเอง

@Query("select count(sl) from SlUrl sl where sl.user =?1 And sl.creationDate between ?2 And ?3")
    long countUrlsBetweenDates(User user, Date date1, Date date2);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.