มีวิธีสร้างแบบสอบถามที่แตกต่างใน HQL หรือไม่ ไม่ว่าจะโดยใช้คำหลัก "เฉพาะ" หรือวิธีอื่น ๆ ฉันไม่แน่ใจว่าความแตกต่างเป็นคีย์เวิร์กที่ถูกต้องสำหรับ HQL หรือไม่ แต่ฉันกำลังมองหา HQL ที่เทียบเท่ากับคำหลัก SQL
มีวิธีสร้างแบบสอบถามที่แตกต่างใน HQL หรือไม่ ไม่ว่าจะโดยใช้คำหลัก "เฉพาะ" หรือวิธีอื่น ๆ ฉันไม่แน่ใจว่าความแตกต่างเป็นคีย์เวิร์กที่ถูกต้องสำหรับ HQL หรือไม่ แต่ฉันกำลังมองหา HQL ที่เทียบเท่ากับคำหลัก SQL
คำตอบ:
นี่คือตัวอย่างของ hql ที่เราใช้ (ชื่อถูกเปลี่ยนเพื่อปกป้องตัวตน)
String queryString = "select distinct f from Foo f inner join foo.bars as b" +
" where f.creationDate >= ? and f.creationDate < ? and b.bar = ?";
return getHibernateTemplate().find(queryString, new Object[] {startDate, endDate, bar});
เป็นที่น่าสังเกตว่าdistinct
คีย์เวิร์ดใน HQL ไม่ได้แมปโดยตรงกับdistinct
คีย์เวิร์ดใน SQL
หากคุณใช้distinct
คีย์เวิร์ดใน HQL บางครั้งไฮเบอร์เนตจะใช้distinct
คีย์เวิร์ด SQL แต่ในบางสถานการณ์จะใช้ตัวแปลงผลลัพธ์เพื่อสร้างผลลัพธ์ที่แตกต่างกัน ตัวอย่างเช่นเมื่อคุณใช้การรวมภายนอกเช่นนี้:
select distinct o from Order o left join fetch o.lineItems
เป็นไปไม่ได้ที่จะกรองรายการที่ซ้ำกันในระดับ SQL ในกรณีนี้ดังนั้นไฮเบอร์เนตจึงใช้ResultTransformer
เพื่อกรองรายการที่ซ้ำกันหลังจากที่ดำเนินการสืบค้น SQL แล้ว
ทำอะไรแบบนี้ในครั้งต่อไป
Criteria crit = (Criteria) session.
createCriteria(SomeClass.class).
setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
List claz = crit.list();
คุณยังสามารถใช้Criteria.DISTINCT_ROOT_ENTITY
กับแบบสอบถาม Hibernate HQL ได้เช่นกัน
ตัวอย่าง:
Query query = getSession().createQuery("from java_pojo_name");
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return query.list();
ฉันมีปัญหาบางอย่างกับตัวแปลงผลลัพธ์รวมกับแบบสอบถาม HQL เมื่อได้ลองแล้ว
final ResultTransformer trans = new DistinctRootEntityResultTransformer();
qry.setResultTransformer(trans);
มันไม่ได้ผล ฉันต้องแปลงร่างด้วยตนเองดังนี้:
final List found = trans.transformList(qry.list());
ด้วย Criteria API transformers ทำงานได้ดี
ข้อความค้นหาหลักของฉันมีลักษณะเช่นนี้ในโมเดล:
@NamedQuery(name = "getAllCentralFinancialAgencyAccountCd",
query = "select distinct i from CentralFinancialAgencyAccountCd i")
และฉันก็ยังไม่ได้รับสิ่งที่ฉันคิดว่าเป็นผลลัพธ์ที่ "แตกต่าง" พวกเขาแตกต่างกันเพียงแค่ขึ้นอยู่กับคีย์ผสมหลักบนตาราง
ดังนั้นDaoImpl
ฉันจึงเพิ่มการเปลี่ยนแปลงหนึ่งบรรทัดและได้รับผลตอบแทนที่ "แตกต่าง" ตามที่ฉันต้องการ ตัวอย่างเช่นแทนที่จะเห็น 00 สี่ครั้งตอนนี้ฉันเห็นเพียงครั้งเดียว นี่คือรหัสที่ฉันเพิ่มในDaoImpl
:
@SuppressWarnings("unchecked")
public List<CacheModelBase> getAllCodes() {
Session session = (Session) entityManager.getDelegate();
org.hibernate.Query q = session.getNamedQuery("getAllCentralFinancialAgencyAccountCd");
q.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // This is the one line I had to add to make it do a more distinct query.
List<CacheModelBase> codes;
codes = q.list();
return codes;
}
ฉันหวังว่านี่จะช่วยได้! อีกครั้งสิ่งนี้อาจใช้ได้ผลก็ต่อเมื่อคุณปฏิบัติตามแนวทางการเขียนโค้ดที่ใช้บริการ dao และประเภทโมเดลของโครงการ
สมมติว่าคุณมีเอนทิตีลูกค้าที่แมปกับตาราง CUSTOMER_INFORMATION และคุณต้องการได้รับรายชื่อชื่อลูกค้าที่แตกต่างกัน คุณสามารถใช้ตัวอย่างข้อมูลด้านล่างเพื่อรับสิ่งเดียวกัน
Query distinctFirstName = session.createQuery("select ci.firstName from Customer ci group by ci.firstName");
Object [] firstNamesRows = distinctFirstName.list();
ฉันหวังว่ามันจะช่วยได้ ดังนั้นเราจึงใช้ group by แทนที่จะใช้คำหลักที่แตกต่างกัน
ก่อนหน้านี้ฉันพบว่ามันยากที่จะใช้คำสำคัญที่แตกต่างกันเมื่อฉันต้องการใช้กับหลายคอลัมน์ ตัวอย่างเช่นฉันต้องการรับรายชื่อของ firstName ที่แตกต่างกัน lastName จากนั้นจัดกลุ่มโดยใช้ ฉันมีปัญหาในการใช้ความแตกต่างในกรณีนี้
ฉันได้รับคำตอบสำหรับ Hibernate Query Language เพื่อใช้เขตข้อมูลที่แตกต่างกัน คุณสามารถใช้ * SELECT DISTINCT (TO_CITY) จาก FLIGHT_ROUTE * หากคุณใช้แบบสอบถามSQLจะส่งคืนรายการสตริง คุณไม่สามารถใช้มันส่งคืนค่าโดยเอนทิตีคลาส ดังนั้นคำตอบในการแก้ประเภทของปัญหาที่มีการใช้งานHQLกับSQL
FROM FLIGHT_ROUTE F WHERE F.ROUTE_ID IN (SELECT SF.ROUTE_ID FROM FLIGHT_ROUTE SF GROUP BY SF.TO_CITY);
จากSQLคำสั่งแบบสอบถามมี DISTINCT ROUTE_ID และอินพุตเป็นรายการ และในแบบสอบถามกรอง TO_CITY ที่แตกต่างจาก IN (รายการ)
ประเภท Return คือประเภท Entity Bean ดังนั้นคุณจึงสามารถใน AJAX เช่นAutoComplement
ทั้งหมดอาจจะโอเค
คุณสามารถใช้คำหลักที่แตกต่างกันได้ในเครื่องมือสร้างเกณฑ์ของคุณเช่นนี้
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Orders> query = builder.createQuery(Orders.class);
Root<Orders> root = query.from(Orders.class);
query.distinct(true).multiselect(root.get("cust_email").as(String.class));
และสร้างตัวสร้างฟิลด์ในคลาสโมเดลของคุณ
หากคุณจำเป็นต้องใช้คำหลักใหม่สำหรับ DTO ที่กำหนดเองในคำสั่งที่คุณเลือกและต้องการองค์ประกอบที่แตกต่างกันให้ใช้คำหลักใหม่นอกเหนือจากสิ่งใหม่ดังนี้ -
select distinct new com.org.AssetDTO(a.id, a.address, a.status) from Asset as a where ...
คุณสามารถเพิ่ม GROUP BY แทน Distinct ได้
@Query(value = "from someTableEntity where entityCode in :entityCode" +
" group by entityCode, entityName, entityType")
List<someTableEntity > findNameByCode(@Param("entityCode") List<String> entityCode);