การเพิ่มในรายการประโยคไปยังแบบสอบถาม JPA


125

ฉันได้สร้าง NamedQuery ที่มีลักษณะดังนี้:

@NamedQuery(name = "EventLog.viewDatesInclude",
        query = "SELECT el FROM EventLog el WHERE el.timeMark >= :dateFrom AND "
        + "el.timeMark <= :dateTo AND "
        + "el.name IN (:inclList)")

สิ่งที่ฉันต้องการทำคือกรอกพารามิเตอร์: inclList ด้วยรายการของรายการแทนที่จะเป็นรายการเดียว ตัวอย่างเช่นหากฉันมีฉันจะหาnew List<String>() { "a", "b", "c" }สิ่งนั้นในพารามิเตอร์: inclList ได้อย่างไร มันช่วยให้ฉันเข้ารหัสหนึ่งสตริงเท่านั้น ตัวอย่างเช่น:

setParameter("inclList", "a") // works

setParameter("inclList", "a, b") // does not work

setParameter("inclList", "'a', 'b'") // does not work

setParameter("inclList", list) // throws an exception

ฉันรู้ว่าฉันสามารถสร้างสตริงและสร้างแบบสอบถามทั้งหมดจากสิ่งนั้น แต่ฉันต้องการหลีกเลี่ยงค่าใช้จ่าย มีวิธีที่ดีกว่านี้หรือไม่?

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


นี่เป็นสำเนาของstackoverflow.com/questions/1557085/…แต่ชุดข้อความนี้ให้คำตอบที่เป็นประโยชน์
Mike Ryan

คำตอบ:


182

เมื่อใช้INกับพารามิเตอร์มูลค่าคอลเลกชันคุณไม่จำเป็นต้อง(...):

@NamedQuery(name = "EventLog.viewDatesInclude", 
    query = "SELECT el FROM EventLog el WHERE el.timeMark >= :dateFrom AND " 
    + "el.timeMark <= :dateTo AND " 
    + "el.name IN :inclList") 

6
ไม่ ... กรณีของฉันมันตรงกันข้าม ถ้าฉันใช้: inclList แสดงว่ามันไม่ทำงาน ถ้าฉันใช้ IN (: inclList) มันก็ใช้ได้
Gunjan Shah

1
นอกจากนี้โปรดทราบว่าประเภทของพารามิเตอร์ของคุณต้องเป็นคอลเล็กชัน (ไม่ใช่อาร์เรย์) ของวัตถุ วัตถุต้องตรงกับประเภทของฟิลด์ .toString () ไม่ใช้แทนคลาส String
dube

2
ฉันคิดว่านี่เป็นสิ่งที่เปลี่ยนแปลงไปกับเวอร์ชันของ Hibernate เท่าที่ฉันจำได้ฉันได้รับข้อผิดพลาดเมื่อไม่มี paranthesis รอบตัวแปรเมื่อใช้ IN แปลกถ้ามันเข้ากันไม่ได้ ..
Tobb

1
นี่เป็นข้อผิดพลาดในการจำศีล (ความต้องการของวงเล็บ) ซึ่งได้รับการแก้ไขแล้วใน 3.6.1
Mat

1
สำหรับคำถามที่เกี่ยวข้อง: ในกรณีที่มีรายการใหญ่มากอาจมีข้อ จำกัด ในการนำไปใช้งาน เช่น oracle 11g. สูงสุด องค์ประกอบรายการ 1,000 รายการเป็นพารามิเตอร์ที่เป็นไปได้ วิธีแก้ปัญหาคือการสับรายการในรายการย่อยและรวบรวมผลลัพธ์ JPA เองไม่ได้ จำกัด ขนาดรายการ
Mahttias Schrebiér

81

รูปแบบแบบสอบถาม JPA ที่เหมาะสมจะเป็น:

el.name IN :inclList

หากคุณใช้ Hibernate เวอร์ชันเก่ากว่าเป็นผู้ให้บริการของคุณคุณต้องเขียน:

el.name IN (:inclList)

แต่นั่นเป็นข้อบกพร่อง ( HHH-5126 ) (แก้ไข: ซึ่งได้รับการแก้ไขแล้วในขณะนี้)


5
ขอบคุณสำหรับการแยกแยะการใช้งาน Hibernate เวอร์ชันเก่า ()
Rob L

32
public List<DealInfo> getDealInfos(List<String> dealIds) {
        String queryStr = "SELECT NEW com.admin.entity.DealInfo(deal.url, deal.url, deal.url, deal.url, deal.price, deal.value) " + "FROM Deal AS deal where deal.id in :inclList";
        TypedQuery<DealInfo> query = em.createQuery(queryStr, DealInfo.class);
        query.setParameter("inclList", dealIds);
        return query.getResultList();
    }

ใช้งานได้กับ JPA 2, Jboss 7.0.2


9

คุณต้องแปลงListเป็นดังที่แสดงด้านล่าง:

    String[] valores = hierarquia.split(".");       
    List<String> lista =  Arrays.asList(valores);

    String jpqlQuery = "SELECT a " +
            "FROM AcessoScr a " +
            "WHERE a.scr IN :param ";

    Query query = getEntityManager().createQuery(jpqlQuery, AcessoScr.class);                   
    query.setParameter("param", lista);     
    List<AcessoScr> acessos = query.getResultList();

ขอบคุณคำตอบนี้ช่วยฉันได้
cabaji99
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.