โซลูชันสำหรับแบบสอบถาม JPQL
นี้ได้รับการสนับสนุนสำหรับการค้นหา JPQL ภายในข้อกำหนด JPA
ขั้นตอนที่ 1 : ประกาศคลาสถั่วง่ายๆ
package com.path.to;
public class SurveyAnswerStatistics {
private String answer;
private Long cnt;
public SurveyAnswerStatistics(String answer, Long cnt) {
this.answer = answer;
this.count = cnt;
}
}
ขั้นตอนที่ 2 : ส่งคืนอินสแตนซ์ bean จากเมธอดที่เก็บ
public interface SurveyRepository extends CrudRepository<Survey, Long> {
@Query("SELECT " +
" new com.path.to.SurveyAnswerStatistics(v.answer, COUNT(v)) " +
"FROM " +
" Survey v " +
"GROUP BY " +
" v.answer")
List<SurveyAnswerStatistics> findSurveyCount();
}
หมายเหตุสำคัญ
- ตรวจสอบให้แน่ใจว่าได้ระบุพา ธ แบบเต็มไปยังคลาส bean รวมถึงชื่อแพ็กเกจ ตัวอย่างเช่นถ้าระดับถั่วที่เรียกว่า
MyBean
และมันก็เป็นในแพคเกจเส้นทางที่มีคุณสมบัติครบถ้วนที่จะถั่วจะเป็นcom.path.to
com.path.to.MyBean
การให้เพียงอย่างเดียวMyBean
จะไม่ทำงาน (เว้นแต่คลาส bean จะอยู่ในแพ็คเกจเริ่มต้น)
- ตรวจสอบให้แน่ใจว่าได้เรียกตัวสร้างคลาส bean โดยใช้
new
คีย์เวิร์ด SELECT new com.path.to.MyBean(...)
จะทำงานในขณะที่SELECT com.path.to.MyBean(...)
จะไม่
- ตรวจสอบให้แน่ใจว่าได้ส่งแอตทริบิวต์ในลำดับเดียวกันกับที่คาดไว้ในตัวสร้าง bean การพยายามส่งผ่านแอตทริบิวต์ในลำดับที่แตกต่างกันจะนำไปสู่ข้อยกเว้น
- ตรวจสอบให้แน่ใจว่าแบบสอบถามเป็นแบบสอบถาม JPA ที่ถูกต้องนั่นคือไม่ใช่การสืบค้นดั้งเดิม
@Query("SELECT ...")
หรือ@Query(value = "SELECT ...")
หรือ@Query(value = "SELECT ...", nativeQuery = false)
จะทำงานในขณะที่@Query(value = "SELECT ...", nativeQuery = true)
จะไม่ทำงาน เนื่องจากแบบสอบถามเนทีฟถูกส่งโดยไม่มีการปรับเปลี่ยนไปยังผู้ให้บริการ JPA และจะดำเนินการกับ RDBMS ที่อยู่ภายใต้เงื่อนไขดังกล่าว เนื่องจากnew
และcom.path.to.MyBean
ไม่ใช่คีย์เวิร์ด SQL ที่ถูกต้อง RDBMS จึงแสดงข้อยกเว้น
โซลูชันสำหรับแบบสอบถามเนทีฟ
ดังที่ระบุไว้ข้างต้นnew ...
ไวยากรณ์เป็นกลไกที่รองรับ JPA และทำงานร่วมกับผู้ให้บริการ JPA ทั้งหมด อย่างไรก็ตามหากแบบสอบถามนั้นไม่ใช่คิวรี JPA นั่นคือเป็นการสืบค้นnew ...
แบบเนทีฟไวยากรณ์จะไม่ทำงานเนื่องจากแบบสอบถามถูกส่งต่อโดยตรงไปยัง RDBMS ที่อยู่ข้างใต้ซึ่งไม่เข้าใจnew
คำหลักเนื่องจากไม่ได้เป็นส่วนหนึ่งของ มาตรฐาน SQL
ในสถานการณ์เช่นนี้คลาส bean จำเป็นต้องถูกแทนที่ด้วยอินเทอร์เฟซSpring Data Projection
ขั้นตอนที่ 1 : ประกาศอินเทอร์เฟซการฉายภาพ
package com.path.to;
public interface SurveyAnswerStatistics {
String getAnswer();
int getCnt();
}
ขั้นตอนที่ 2 : ส่งคืนคุณสมบัติที่คาดการณ์ไว้จากแบบสอบถาม
public interface SurveyRepository extends CrudRepository<Survey, Long> {
@Query(nativeQuery = true, value =
"SELECT " +
" v.answer AS answer, COUNT(v) AS cnt " +
"FROM " +
" Survey v " +
"GROUP BY " +
" v.answer")
List<SurveyAnswerStatistics> findSurveyCount();
}
ใช้AS
คีย์เวิร์ดSQL เพื่อแม็พฟิลด์ผลลัพธ์กับคุณสมบัติการฉายสำหรับการแม็พที่ไม่คลุมเครือ
Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Unable to locate class [SurveyAnswerReport] [select new SurveyAnswerReport(v.answer,count(v.id)) from com.furniturepool.domain.Survey v group by v.answer] at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1750) at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677) at org.hibernate.jpa.spi.AbstractEnti..........