JPA และ Hibernate - เกณฑ์เทียบกับ JPQL หรือ HQL


295

ข้อดีและข้อเสียของการใช้CriteriaหรือHQLคืออะไร Criteria API เป็นวิธีเชิงวัตถุที่ดีในการแสดงคำค้นหาใน Hibernate แต่บางครั้ง Queries Queries นั้นยากต่อการเข้าใจ / build มากกว่า HQL

คุณใช้เกณฑ์เมื่อใดและเมื่อใด HQL คุณต้องการใช้กรณีใด? หรือมันเป็นเพียงเรื่องของการลิ้มรส?


คำตอบที่ถูกต้องคือ 'ขึ้นอยู่กับกรณีการใช้งาน'
Hace

แล้วเครื่องมือนี้ล่ะ? จะช่วยให้การสร้างแบบสอบถามทั่วไปในทางวัตถุ: การป้องกันข้อเลือก () {return em.select ("DISTINCT i"). จาก (this.getName (), "i") .joinFetch ("i.locale lf") } สาธารณะ T findBySlug (สตริงกระสุน) {return (T) this.select () .join ("i.locale l"); .where ("l.slug =?", กระสุน) .fetchSingle (); }
Vojtěch

1
คำจำกัดความของคำถามตามความคิดเห็น แต่คนยังไม่ได้มีโอกาสปิด ... ตามเว็บไซต์คำถามที่พบบ่อย

คำตอบ:


212

ฉันส่วนใหญ่ชอบการค้นหาเกณฑ์สำหรับการค้นหาแบบไดนามิก ตัวอย่างเช่นการเพิ่มการสั่งซื้อแบบไดนามิกนั้นง่ายกว่ามากหรือปล่อยให้บางส่วนออกไป (เช่นข้อ จำกัด ) ขึ้นอยู่กับพารามิเตอร์บางตัว

ในทางกลับกันฉันใช้ HQL สำหรับการค้นหาแบบคงที่และซับซ้อนเนื่องจากง่ายต่อการเข้าใจ / อ่าน HQL มากขึ้น นอกจากนี้ HQL นั้นมีประสิทธิภาพมากกว่าฉันคิดเช่นสำหรับประเภทการเข้าร่วมที่แตกต่างกัน


13
นอกจากนี้แม้ว่าเกณฑ์จะดูปลอดภัยกว่าประเภทเล็กน้อย แต่สิ่งเดียวที่ทำให้คุณรู้สึกปลอดภัยคือการทดสอบ

มีตัวอย่างที่ดีที่แสดงว่าทำไม HQL ดีกว่าเกณฑ์ API ในบางกรณี? ฉันอ่านจุดจบของบล็อกเดียว แต่ไม่เข้าใจอะไรเลย จะขอบคุณถ้าคุณสามารถช่วย ขอบคุณ Link - javalobby.org/articles/hibernatequery102
Erran Morad

เหตุผลทั้งหมดข้างต้น - ฉันชอบ Criteria to HQL เพราะปลอดภัยต่อโปรแกรมเมอร์ลดข้อผิดพลาดในการเขียนโค้ด - การคอมไพล์บนสตริง HQL ไม่ได้รับการตรวจสอบ
nuno

อย่างไรก็ตามมีปัญหาในการเรียกข้อมูลเอนทิตีที่แตกต่างกันในขณะที่ให้เลขหน้า เมื่อทำเช่นนี้ฉันจะเลือก HQL เพื่อหลีกเลี่ยงปัญหา ...
Anthony Webster

ใช้การสืบค้นเกณฑ์ด้วย metamodel สำหรับชื่อคอลัมน์ช่วยในระหว่างการเปลี่ยนโครงสร้างใหม่เพื่อไม่ทำลายสิ่งใดและด้วยคำสั่งง่าย ๆ จาก IDE สมัยใหม่เพื่อเปลี่ยนชื่อการเกิดขึ้นทั้งหมดในรหัส
Massimo

92

มีความแตกต่างในแง่ของประสิทธิภาพระหว่าง HQL และ criteriaQuery ทุกครั้งที่คุณเรียกใช้คิวรีโดยใช้QueryQueryมันจะสร้างนามแฝงใหม่สำหรับชื่อตารางซึ่งไม่ได้สะท้อนถึงแคชที่สอบถามล่าสุดสำหรับฐานข้อมูลใด ๆ สิ่งนี้นำไปสู่ค่าใช้จ่ายในการรวบรวม SQL ที่สร้างขึ้นใช้เวลาในการดำเนินการมากขึ้น

เกี่ยวกับกลยุทธ์การดึงข้อมูล[http://www.hibernate.org/315.html]

  • เกณฑ์เคารพการตั้งค่าความเกียจคร้านในการจับคู่และรับประกันว่าสิ่งที่คุณต้องการโหลดจะถูกโหลด ซึ่งหมายความว่าหนึ่งแบบสอบถามเกณฑ์อาจส่งผลให้หลายคำสั่ง SELECT ทันที SQL เพื่อดึงกราฟย่อยที่มีการเชื่อมโยงและคอลเลกชันที่แมปที่ไม่ขี้เกียจทั้งหมด หากคุณต้องการเปลี่ยน "อย่างไร" และแม้แต่ "อะไร" ให้ใช้ setFetchMode () เพื่อเปิดใช้งานหรือปิดใช้งานการดึงข้อมูลการเข้าร่วมด้านนอกสำหรับการรวบรวมหรือการเชื่อมโยงที่เฉพาะเจาะจง คิวรีเกณฑ์ยังเคารพกลยุทธ์การดึงข้อมูล (เข้าร่วม vs select select vs subselect)
  • HQL เคารพการตั้งค่าความเกียจคร้านในการจับคู่ของคุณและรับประกันว่าสิ่งที่คุณต้องการโหลดจะถูกโหลด ซึ่งหมายความว่าหนึ่งแบบสอบถาม HQL อาจส่งผลให้หลายคำสั่ง SELECT ทันที SQL เพื่อดึงกราฟย่อยที่มีการเชื่อมโยงและคอลเลกชันที่ไม่ได้ขี้เกียจทั้งหมด หากคุณต้องการเปลี่ยน "อย่างไร" และแม้แต่ "อะไร" ให้ใช้ซ้ายเข้าร่วม FETCH เพื่อเปิดใช้งานการดึงข้อมูลเข้าร่วมภายนอกสำหรับคอลเล็กชันที่เฉพาะเจาะจงหรือเป็นโมฆะหลายต่อหนึ่งหรือหนึ่งต่อหนึ่งหรือเข้าร่วมเพื่อเปิดใช้งาน การเข้าร่วมแบบดึงภายในสำหรับการเชื่อมโยงแบบหลายต่อหนึ่งหรือแบบหนึ่งต่อหนึ่งที่ไม่ใช่ค่า null แบบสอบถาม HQL ไม่เคารพ fetch = "เข้าร่วม" ใด ๆ ที่กำหนดไว้ในเอกสารการทำแผนที่

1
เพียงแค่ชี้ให้ทุกคนที่กำลังดู คำตอบนี้มาจากปี 2008 ซึ่งอาจไม่เป็นเช่นนั้นอีกแล้ว dimovelev.blogspot.com/2015/02/…
Amalgovinus

41

Criteria เป็น API เชิงวัตถุในขณะที่ HQL หมายถึงการต่อสตริง นั่นหมายถึงผลประโยชน์ทั้งหมดของการมุ่งเน้นวัตถุ:

  1. สิ่งอื่น ๆ ที่เท่ากันรุ่น OO นั้นมีแนวโน้มที่จะเกิดข้อผิดพลาดได้ค่อนข้างน้อย สตริงเก่าใด ๆ สามารถผนวกเข้ากับแบบสอบถาม HQL ในขณะที่วัตถุเกณฑ์ที่ถูกต้องเท่านั้นที่สามารถทำให้มันกลายเป็นต้นไม้เกณฑ์ อย่างมีประสิทธิภาพคลาส Criteria จะถูก จำกัด มากขึ้น
  2. ด้วยการเติมข้อมูลอัตโนมัติ OO จึงสามารถค้นพบได้มากขึ้น (อย่างน้อยก็ใช้ง่ายกว่าสำหรับฉัน) คุณไม่จำเป็นต้องจำส่วนใดของการสืบค้น IDE สามารถช่วยคุณได้
  3. คุณไม่จำเป็นต้องจำรายละเอียดของไวยากรณ์ (เช่นสัญลักษณ์ที่ไปที่ใด) สิ่งที่คุณต้องรู้คือวิธีการโทรวิธีการและสร้างวัตถุ

เนื่องจาก HQL นั้นเหมือนกับ SQL (ซึ่ง devs ส่วนใหญ่รู้จักดีอยู่แล้ว) ดังนั้นข้อโต้แย้ง "ไม่ต้องจำ" เหล่านี้จึงไม่มีน้ำหนัก ถ้า HQL แตกต่างกันมากกว่านี้ก็จะเป็นการนำเข้ามากกว่าเดิม


12
ข้อโต้แย้งเหล่านี้ไม่ถือน้ำ (เกี่ยวกับ HQL) มันไม่จำเป็นต้องเกี่ยวข้องกับการต่อสตริง ว่าเวอร์ชั่น OO นั้นมีแนวโน้มที่จะเกิดข้อผิดพลาดน้อยกว่านั้นไม่มีความแน่นอน มันมีแนวโน้มที่จะเกิดข้อผิดพลาดอย่างเท่าเทียมกัน แต่แตกต่างกัน ความพยายามในการรู้ว่าวิธีการโทรแบบใดนั้นไม่แตกต่างจากการรู้ว่าจะใช้สัญลักษณ์ใดใน HQL (ฉันหมายถึงอย่างจริงจังเราไม่ได้แก้ไข PDE ที่นี่)
luis.espinal

มีตัวอย่างที่ดีที่แสดงว่าทำไม HQL ดีกว่าเกณฑ์ API ในบางกรณี? ฉันอ่านจุดจบของบล็อกเดียว แต่ไม่เข้าใจอะไรเลย จะขอบคุณถ้าคุณสามารถช่วย ขอบคุณ Link - javalobby.org/articles/hibernatequery102
Erran Morad

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

การทำให้สมบูรณ์อัตโนมัติในเกณฑ์ค่อนข้างไร้ประโยชน์เพราะคุณสมบัติเป็นเพียงสตริง
Lluis Martinez

35

ฉันมักจะใช้เกณฑ์เมื่อไม่ทราบว่าจะใช้ปัจจัยใดในข้อมูลส่วนใด เช่นเดียวกับในแบบฟอร์มการค้นหาที่ผู้ใช้สามารถป้อนรายการใด ๆ จาก 1 ถึง 50 รายการและฉันทำสิ่งที่พวกเขากำลังค้นหา มันง่ายมากที่จะต่อท้ายเกณฑ์เมื่อฉันตรวจสอบสิ่งที่ผู้ใช้ค้นหา ฉันคิดว่ามันจะลำบากกว่านิดหน่อยที่จะใส่เคียวรี HQL ในสถานการณ์นั้น HQL นั้นยอดเยี่ยม แต่เมื่อฉันรู้อย่างแน่นอนว่าฉันต้องการอะไร


1
นี่เป็นความคิดเห็นที่ดี ขณะนี้เราสร้างสตริง HQL ที่มีขนาดใหญ่มากสำหรับแบบฟอร์มการค้นหาที่มีวัตถุที่แตกต่างกันมากมายผ่านการรวม ดูน่าเกลียด ไปดูว่าเกณฑ์สามารถทำความสะอาดได้หรือไม่ น่าสนใจ ...
cbmeeks

ขอบคุณ นี่เป็นตัวอย่างที่ยอดเยี่ยม คุณช่วยมอบเพิ่มเติมให้ฉันได้ไหม
Erran Morad

31

HQL นั้นง่ายต่อการอ่านมากขึ้นง่ายต่อการดีบักโดยใช้เครื่องมือเช่นปลั๊กอิน Eclipse Hibernate และเข้าสู่ระบบได้ง่ายขึ้น คิวรีเกณฑ์จะดีกว่าสำหรับการสร้างคิวรีแบบไดนามิกที่มีการกำหนดลักษณะการทำงานจำนวนมาก ณ รันไทม์ ถ้าคุณไม่รู้ SQL ฉันสามารถเข้าใจได้โดยใช้คิวรี Criteria แต่โดยรวมแล้วฉันชอบ HQL ถ้าฉันรู้ว่าฉันต้องการอะไรล่วงหน้า


22

เกณฑ์เป็นวิธีเดียวที่จะระบุการค้นหาคีย์ธรรมชาติที่ใช้ประโยชน์จากการปรับแต่งพิเศษในแคชคิวรีระดับที่สอง HQL ไม่มีวิธีใด ๆ ในการระบุคำใบ้ที่จำเป็น

คุณสามารถหาข้อมูลเพิ่มเติมได้ที่นี่:


21

Cri Api เป็นหนึ่งในแนวคิดที่ดีของ Hibernate ตามมุมมองของฉันสิ่งเหล่านี้เป็นเพียงไม่กี่จุดที่เราสามารถสร้างความแตกต่างระหว่างHQLและApi ของเกณฑ์

  1. HQL คือการดำเนินการทั้งเลือกและไม่เลือกข้อมูล แต่เกณฑ์เป็นเพียงการเลือกข้อมูลเราไม่สามารถดำเนินการที่ไม่ใช่เลือกโดยใช้เกณฑ์
  2. HQL เหมาะสำหรับการเรียกใช้งานแบบสอบถามแบบคงที่ซึ่งเป็นเกณฑ์ที่เหมาะสมสำหรับการดำเนินการแบบสอบถามแบบไดนามิก
  3. HQL ไม่สนับสนุนแนวคิดการแบ่งหน้าแต่เราสามารถบรรลุการแบ่งหน้าด้วยเกณฑ์
  4. เกณฑ์ที่ใช้ในการดำเนินการมากกว่า HQL
  5. ด้วยเกณฑ์เราปลอดภัยด้วยการฉีด SQLเนื่องจากการสร้างคิวรีแบบไดนามิก แต่ใน HQL เนื่องจากคิวรีของคุณมีการแก้ไขหรือแบบ parametrized ไม่มีความปลอดภัยจากการฉีด SQL

11
มีการแบ่งจุดสองจุดใน HQL: คุณสามารถใช้limit offset:rows ใน hql คุณสามารถหลีกเลี่ยงการฉีด sql โดยใช้setParameter
Viswanath Lekshmanan

13

หากต้องการใช้งานที่ดีที่สุดของโลกทั้งที่ expressivity รัดกุม HQL และลักษณะของเกณฑ์การพิจารณาใช้Querydsl

Querydsl รองรับ JPA / Hibernate, JDO, SQL และ Collections

ฉันเป็นผู้ดูแลของ Querydsl ดังนั้นคำตอบนี้จึงมีอคติ


13

สำหรับฉันเกณฑ์เป็นเรื่องง่ายมากที่จะเข้าใจและสร้างแบบสอบถามแบบไดนามิก แต่ข้อบกพร่องที่ฉันพูดไปนั้นคือมันโหลดความสัมพันธ์แบบหลายคนทั้งหมดเพราะเรามี FetchModes เพียงสามประเภทคือ Select, Proxy และ Default และในทุกกรณีเหล่านี้มันจะโหลดหลายคน (อาจเป็นฉันผิดถ้าช่วยได้ ฉันออก :))

ปัญหาที่ 2 กับเกณฑ์คือว่ามันโหลดวัตถุที่สมบูรณ์เช่นถ้าฉันต้องการที่จะ EmpName โหลดเพียงพนักงานมันเคยชินมาด้วยนี้ insted มันเกิดขึ้นกับวัตถุพนักงานที่สมบูรณ์และฉันจะได้รับ EmpName จากมันเนื่องจากนี้จริงๆมันไม่ดีในการทำงาน รายงาน ที่ HQL เพิ่งโหลด (ไม่ได้โหลดการเชื่อมโยง / ความสัมพันธ์) สิ่งที่คุณต้องการเพิ่มประสิทธิภาพหลาย ๆ ครั้ง

หนึ่งในคุณสมบัติของ Criteria ก็คือมันจะปลอดภัย u จาก SQL Injection เนื่องจากการสร้างเคียวรีแบบไดนามิกซึ่งเหมือนกับใน HQL เมื่อเคียวรี ur คงที่หรือแปรตามพารามิเตอร์ดังนั้นจึงไม่ปลอดภัยจาก SQL Injection

นอกจากนี้หากคุณเขียน HQL ในไฟล์ ur aspx.cs คุณจะถูกผนวกเข้ากับ ur DAL อย่างแน่นหนา

โดยรวมข้อสรุปของฉันคือมีสถานที่ที่คุณไม่สามารถอยู่ได้หากปราศจาก HQL เช่นรายงานดังนั้นให้ใช้เกณฑ์อื่นจัดการได้ง่ายกว่า


13
HQL ไม่ปลอดภัยในการฉีด SQL
Varun Mehta

ฉันคิดว่าเกณฑ์ไม่ปลอดภัยสำหรับการฉีด ดูโพสต์ของฉันที่นี่: stackoverflow.com/questions/6746486/…
มิสเตอร์สมิ ธ

4
HQL IS sql injection ปลอดภัยด้วยการเพิ่ม 'setParameter'
Javatar

2
@Zafar: คุณสามารถเลือกเฉพาะคุณสมบัติของเอนทิตีโดยใช้การคาดการณ์
Răzvan Flavius ​​Panda

@Zafar คุณสามารถตั้งค่าการฉายในคิวรีเกณฑ์เพื่อเลือกคอลัมน์เฉพาะ คุณสามารถดึงข้อมูล EmpName โดยไม่จำเป็นต้องดึงข้อมูลวัตถุที่สมบูรณ์
Khatri

12

API เกณฑ์

API ของเกณฑ์เหมาะสำหรับการสืบค้นที่สร้างขึ้นแบบไดนามิก ดังนั้นถ้าคุณต้องการที่จะเพิ่มฟิลเตอร์ WHERE ข้อ JOIN ข้อแตกต่างกันหรืออนุประโยคสั่ง BY หรือคอลัมน์ฉายแล้วเกณฑ์ API สามารถช่วยให้คุณสร้างแบบสอบถามแบบไดนามิกในทางที่ยังช่วยป้องกันการโจมตี SQL Injection

บนมืออื่น ๆ , คำสั่งเกณฑ์เป็นที่แสดงออกน้อยและยังสามารถนำไปสู่ความซับซ้อนมากและแบบสอบถาม SQL ไม่มีประสิทธิภาพตามที่อธิบายไว้ในบทความนี้

JPQL และ HQL

JPQL เป็นภาษาคิวรีเอนทิตีมาตรฐาน JPA ในขณะที่ HQL ขยาย JPQL และเพิ่มคุณสมบัติเฉพาะของไฮเบอร์เนต

JPQL และ HQL นั้นแสดงออกและคล้ายกับ SQL มาก ซึ่งแตกต่างจาก Criteria API, JPQL และ HQL ทำให้ง่ายต่อการทำนายเคียวรี SQL ที่สร้างโดยผู้ให้บริการ JPA นอกจากนี้ยังง่ายกว่ามากในการตรวจสอบแบบสอบถาม HQL ของคน ๆ หนึ่งกว่าเกณฑ์

เป็นที่น่าสังเกตว่าการเลือกเอนทิตีด้วย JPQL หรือ Criteria API นั้นสมเหตุสมผลถ้าคุณต้องการแก้ไข มิฉะนั้นการฉาย DTOเป็นทางเลือกที่ดีกว่ามาก

ข้อสรุป

หากคุณไม่ต้องการเปลี่ยนแปลงโครงสร้างคิวรีเอนทิตีให้ใช้ JPQL หรือ HQL หากคุณต้องการเปลี่ยนเกณฑ์การกรองหรือการเรียงลำดับหรือเปลี่ยนการฉายภาพให้ใช้ Criteria API

อย่างไรก็ตามเนื่องจากคุณใช้ JPA หรือ Hibernate ไม่ได้หมายความว่าคุณไม่ควรใช้ SQL ดั้งเดิม การสืบค้น SQL นั้นมีประโยชน์มากและ JPQL และ Criteria API ไม่ใช่การแทนที่สำหรับ SQL ลองอ่านบทความนี้สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับหัวข้อนี้



11

สำหรับฉันการได้รับรางวัลสูงสุดตามเกณฑ์คือ API ตัวอย่างซึ่งคุณสามารถส่งผ่านวัตถุและไฮเบอร์เนตจะสร้างแบบสอบถามตามคุณสมบัติของวัตถุเหล่านั้น

นอกจากนั้นเกณฑ์ API มีนิสัยใจคอของมัน (ฉันเชื่อว่าทีมไฮเบอร์เนตกำลังทำงานอีกครั้ง API) เช่น:

  • a criteria.createAlias ​​("obj") บังคับให้มีการรวมภายในแทนการเข้าร่วมภายนอกที่เป็นไปได้
  • คุณไม่สามารถสร้างนามแฝงเดียวกันสองครั้ง
  • ส่วนคำสั่ง sql บางตัวไม่มีเกณฑ์ง่าย ๆ (เช่นตัวเลือกย่อย)
  • เป็นต้น

ฉันมักจะใช้ HQL เมื่อฉันต้องการแบบสอบถามที่คล้ายกับ sql (ลบจากผู้ใช้ที่ status = 'ถูกบล็อก') และฉันมักจะใช้เกณฑ์เมื่อฉันไม่ต้องการใช้การต่อท้ายสตริง

ข้อดีอีกอย่างของ HQL ก็คือคุณสามารถกำหนดคิวรีทั้งหมดของคุณก่อนถึงมือและแม้แต่ส่งออกไปยังไฟล์หรือมากกว่านั้น


9

Cri api ให้คุณสมบัติหนึ่งที่แตกต่างที่ทั้ง SQL หรือ HQL ให้ กล่าวคือ มันช่วยให้การตรวจสอบเวลารวบรวมของแบบสอบถาม


7

เราใช้เกณฑ์ส่วนใหญ่ในแอปพลิเคชันของเราในตอนแรก แต่หลังจากนั้นก็ถูกแทนที่ด้วย HQL เนื่องจากปัญหาด้านประสิทธิภาพ
ส่วนใหญ่เรากำลังใช้การค้นหาที่ซับซ้อนมากโดยมีการรวมหลายรายการซึ่งนำไปสู่การค้นหาหลายรายการในเกณฑ์ แต่ได้รับการปรับให้เหมาะสมที่สุดใน HQL
กรณีนี้คือเราใช้เพียงแค่การตอบสนองหลายอย่างกับวัตถุเฉพาะและไม่ใช่วัตถุที่สมบูรณ์ ด้วยเกณฑ์ปัญหาก็เป็นสตริงที่ต่อกัน
สมมติว่าถ้าคุณต้องการแสดงชื่อและนามสกุลของผู้ใช้ใน HQL มันค่อนข้างง่าย(name || ' ' || surname)แต่ใน Crteria มันเป็นไปไม่ได้
เพื่อที่จะเอาชนะสิ่งนี้เราได้ใช้ ResultTransormers ซึ่งมีวิธีการเรียงต่อกันที่ถูกนำมาใช้เพื่อผลลัพธ์ที่ต้องการ
วันนี้เราส่วนใหญ่ใช้ HQL เช่นนี้:

String hql = "select " +
            "c.uuid as uuid," +
            "c.name as name," +
            "c.objective as objective," +
            "c.startDate as startDate," +
            "c.endDate as endDate," +
            "c.description as description," +
            "s.status as status," +
            "t.type as type " +
            "from " + Campaign.class.getName() + " c " +
            "left join c.type t " +
            "left join c.status s";

Query query =  hibernateTemplate.getSessionFactory().getCurrentSession().getSession(EntityMode.MAP).createQuery(hql);
query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
return query.list();

ดังนั้นในกรณีของเราระเบียนที่ส่งคืนคือแผนที่ของคุณสมบัติที่ต้องการ


1
ด้วยเกณฑ์คุณสามารถใช้ org.hibernate.criterion.CriteriaSpecification.ALIAS_TO_ENTITY_MAP
AA

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

7
  • HQL คือการดำเนินการทั้งการเลือกและการไม่เลือกข้อมูล แต่เกณฑ์เป็นเพียงการเลือกข้อมูลเราไม่สามารถดำเนินการที่ไม่ใช่เลือกโดยใช้เกณฑ์
  • HQL เหมาะสำหรับการเรียกใช้งานแบบสอบถามแบบคงที่ซึ่งเป็นเกณฑ์ที่เหมาะสมสำหรับการดำเนินการแบบสอบถามแบบไดนามิก
  • HQL ไม่สนับสนุนแนวคิดการแบ่งหน้า แต่เราสามารถบรรลุการแบ่งหน้าด้วยเกณฑ์
  • เกณฑ์ที่ใช้ในการดำเนินการมากขึ้นแล้ว HQL
  • ด้วยเกณฑ์ที่เรามีความปลอดภัยกับ SQL Injection เนื่องจากการสร้างแบบสอบถามแบบไดนามิก แต่ใน HQL เป็นแบบสอบถามของคุณจะคงที่หรือ parametrized ไม่มีความปลอดภัยจากการฉีด SQL

แหล่ง


ในการชี้แจงชี้แจงคิวรีที่ใช้ API เกณฑ์ของไฮเบอร์เนตอาจพร้อมใช้งานสำหรับการสอบถาม แต่เคียวรีเกณฑ์ JPA ครอบคลุมการเลือกอัปเดตและการลบ ดูCriteriaUpdate<T>และCriteriaDelete<T>สำหรับการอ้างอิง
Naros

5

แบบสอบถามเกณฑ์สำหรับแบบไดนามิกเราสามารถสร้างแบบสอบถามตามอินพุตของเรา .. ในกรณีของแบบสอบถาม Hql เป็นแบบสอบถามแบบคงที่เมื่อเราสร้างเราไม่สามารถเปลี่ยนโครงสร้างของแบบสอบถาม


2
ไม่เช่นนั้น ด้วย HQL คุณสามารถตั้งค่าคุณสมบัติด้วยตัวระบุ ':' จากนั้นแทนที่คุณสมบัติเหล่านั้นด้วยค่าที่ไม่ซ้ำกัน ตัวอย่างเช่นแบบสอบถาม q = session.createQuery ("SELECT: aValue FROM my_table"); จากนั้น q.setParameter ("aValue", "some_column_name");
MattC

@MattC ในตัวอย่างของคุณคุณกำลังเปลี่ยนค่าพารามิเตอร์ไม่ใช่โครงสร้างของคิวรี
จักรพรรดิ

4

ฉันไม่ต้องการเตะม้าที่ตายที่นี่ แต่สิ่งสำคัญคือต้องพูดถึงว่าตอนนี้แบบสอบถามเลิกใช้แล้ว ใช้ HQL


1

ฉันยังชอบการค้นหาเกณฑ์สำหรับการค้นหาแบบไดนามิก แต่ฉันชอบ hql สำหรับการลบแบบสอบถามตัวอย่างเช่นถ้าลบระเบียนทั้งหมดจากตารางลูกสำหรับ parent id 'xyz' มันสามารถทำได้ง่ายโดย HQL แต่สำหรับเกณฑ์ API ก่อนอื่นเราต้องใช้จำนวนลบแบบสอบถามที่ n คือจำนวนเด็ก บันทึกตาราง


0

คำตอบส่วนใหญ่ที่นี่ทำให้เข้าใจผิดและพูดถึงว่าCriteria Queriesช้ากว่าHQLซึ่งไม่ใช่กรณี

หากคุณเจาะลึกและทำการทดสอบบางอย่างคุณจะเห็นการค้นหาเกณฑ์ปฏิบัติได้ดีกว่า HQL ปกติมาก

และยังมีเกณฑ์แบบสอบถามคุณจะได้รับวัตถุควบคุม Orientedซึ่งไม่ได้มีกับHQL

สำหรับข้อมูลเพิ่มเติมอ่านคำตอบนี้ที่นี่


0

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


0

โพสต์นี้ค่อนข้างเก่า คำตอบส่วนใหญ่พูดถึงเกณฑ์ไฮเบอร์เนตไม่ใช่เกณฑ์ JPA JPA 2.1 เพิ่ม CriteriaDelete / CriteriaUpdate และ EntityGraph ที่ควบคุมสิ่งที่จะดึงข้อมูล Criteria API ดีกว่าเนื่องจาก Java คือ OO นั่นคือเหตุผลที่ JPA ถูกสร้างขึ้น เมื่อรวบรวม JPQL จะถูกแปลเป็นต้นไม้ AST (รุ่น OO) ก่อนที่จะแปลเป็น SQL


-3

HQL สามารถทำให้เกิดปัญหาด้านความปลอดภัยเช่นการฉีด SQL


11
ปัญหาเหล่านี้ไม่ได้เกิดจาก HQL แต่เกิดจากการขาดความเข้าใจในการพัฒนาซอฟต์แวร์ขั้นพื้นฐาน ฉันสามารถสร้างรหัสที่มีแนวโน้มที่จะโจมตีการฉีด sql ด้วยเกณฑ์ API เช่นกัน
Jens Schauder

1
มันเหมือนกับว่า "การสอบถาม RDBMS จาก Java สามารถทำให้เกิดความกังวลด้านความปลอดภัยการฉีด SQL": D
Czar
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.