ข้อมูลเบื้องต้นเกี่ยวกับ Criteria API

มีสองวิธีในการเขียนแบบสอบถามฐานข้อมูลใน Hibernate:

  • ภาษาคิวรีไฮเบอร์เนต
  • API เกณฑ์

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

ไม่ว่าในกรณีใด คุณไม่สามารถเรียนรู้ Hibernate ได้หากไม่ทำความคุ้นเคยกับ Criteria API ลองเขียนตัวอย่างเล็ก ๆ แล้วเราจะวิเคราะห์ เช่น เราจะขอพนักงานทั้งหมด (Employee) จากฐานข้อมูล นี่คือสิ่งที่เราจะได้รับ:

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Employee> critQuery = builder.createQuery(Employee.class);

Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);

Query<Employee> query = session.createQuery(critQuery);
List<Employee> results = query.getResultList();

ดูซับซ้อน. ลองเขียนแบบสอบถาม HQL เดียวกันเพื่อเปรียบเทียบ:

String hqlQuery = "from Employee";

Query<Employee> query = session.createQuery(hqlQuery);
List<Employee> results = query.getResultList();

โปรดทราบว่าสองบรรทัดสุดท้ายของทั้งสองตัวอย่างเกือบจะเหมือนกัน: เราสร้างวัตถุ Query และใช้เพื่อรับรายการ นี่บอกเป็นนัยว่าบรรทัดที่เหลือกำลังทำสิ่งเดียวกัน

ดูบรรทัดที่ 3 และ 4 ของตัวอย่างแรก:

Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);

ลองเขียนลงในบรรทัดเดียว:

critQuery.select(critQuery.from(Employee.class));

มันไม่เตือนอะไรคุณเลยเหรอ? และถ้าคุณระบายสีให้ต่างออกไปเล็กน้อย:

critQuery.select(critQuery.from(Employee.class));

ใช่ นี่เป็นโครงสร้างที่ซับซ้อนของแบบสอบถาม SELECT FROM

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

เพื่อความเข้าใจที่ดีขึ้นฉันจะยกตัวอย่างเพียงเล็กน้อยเท่านั้น

ขอ 1 . รับพนักงานทุกคนที่มีเงินเดือนสูงกว่า 10,000:

critQuery.select(critQuery.from(Employee.class)).where(builder.gt(root.get("salary"), 10000));

ขอ 2 . รับพนักงานทุกคนที่มีเงินเดือนน้อยกว่า 50,000:

critQuery.select(critQuery.from(Employee.class)).where(builder.lt(root.get("salary"), 50000));

ขอ 3 . รับพนักงานทั้งหมดที่มีตำแหน่งงานที่มีคำว่า "ทดสอบ":

critQuery.select(critQuery.from(Employee.class)).where(builder.like(root.get("occupation"), "%test%"));

คำขอ 4 . รับพนักงานทุกคนที่มีเงินเดือน 10 ถึง 50,000:

critQuery.select(critQuery.from(Employee.class)).where(builder.between(root.get("salary"), 10000, 50000));

คำขอ 5 . รับพนักงานทั้งหมดที่มีชื่อเป็นโมฆะ:

critQuery.select(critQuery.from(Employee.class)).where(builder.isNull(root.get("name")));

คำขอ 6 . รับพนักงานทั้งหมดที่มีชื่อไม่เป็นโมฆะ:

critQuery.select(critQuery.from(Employee.class)).where(builder.isNotNull(root.get("name")));

เป็นเพียงวิธีที่ยุ่งยากในการสร้างแบบสอบถาม:

  • ก่อนอื่นคุณจะได้รับวัตถุตัวสร้างเกณฑ์.
  • จากนั้นใช้เพื่อสร้างวัตถุแบบสอบถามเกณฑ์.
  • จากนั้นคุณก็เริ่มเพิ่มชิ้นส่วนเข้าไปด้วยแบบสอบถามเกณฑ์และตัวสร้างเกณฑ์.

นี่คือวิธีที่คุณสามารถตั้งค่าพารามิเตอร์สำหรับ:

  • เลือก
  • จาก
  • ที่ไหน

ยังใช้ตัวสร้างเกณฑ์คุณสามารถสร้างเงื่อนไขที่แตกต่างกันสำหรับ WHERE

การทำงานขั้นสูงด้วย Criteria API

เมื่อใช้ Criteria API คุณสามารถสร้างคิวรีที่มีความซับซ้อนเท่าใดก็ได้ และนี่คือข่าวดี ตัวอย่างเช่น คุณต้องการคำสั่ง WHERE ที่ซับซ้อน นี่คือวิธีการ:

Predicate greaterThan = builder.gt(root.get("salary"), 1000);
Predicate testers = builder.like(root.get("occupation"), "test%");

critQuery.select(critQuery.from(Employee.class)).where(builder.or(greaterThan, testers));

หากคุณต้องการเขียน AND แทน OR คุณต้องเปลี่ยนบรรทัดสุดท้ายเท่านั้น:

critQuery.select(critQuery.from(Employee.class)).where(builder.and(greaterThan, testers));

ทุกอย่างง่ายมากจริงๆ ให้ฉันให้ตารางพร้อมการเปรียบเทียบเล็กน้อย:

เอสคิวแอล วิธี บันทึกเต็ม
ก<b lt(ก, ข) builder.lt(ก ข)
ก > ข gt(ก ข) builder.gt(ก ข)
หรือ ข หรือ(ก,ข) ตัวสร้างหรือ (a, b)
ก และ ข และ(ก,ข) builder.and(a,b)
ชอบ ข ชอบ (ก, ข) builder.like(a, b)
ระหว่าง (c, d) ระหว่าง (ก, ค, ง) ตัวสร้างระหว่าง (a, c, d)
เป็นโมฆะ isNull(ก) builder.isNull(ก)
ไม่เป็นโมฆะ isNotNull(ก) ตัวสร้าง isNotNull(a)

ทุกอย่างง่ายใช่มั้ย

และเราจะเพิ่มการเรียงลำดับในแบบสอบถามได้อย่างไร? ง่ายมาก:

critQuery.select( critQuery.from(Employee.class) );
critQuery.where( builder.and(greaterThan, testers) );
critQuery.orderBy( builder.asc(root.get("salary"), builder.desc(root.get("joinDate") )

คุณเพียงแค่โทรหาวัตถุแบบสอบถามเกณฑ์วิธีการorderBy()และส่งพารามิเตอร์ที่จำเป็นไปให้

ต่อไปนี้คือลักษณะของข้อความค้นหาเดียวกันใน HQL เปรียบเทียบ:

select * from Employee
where (…) and (…)
order by 'salary' asc, 'joinDate' desc

คุณเพียงแค่ต้องจำ 3 สิ่ง:

  • ตัวดำเนินการหลักเช่น SELECT, FROM, WHERE ถูกเรียกบนวัตถุแบบสอบถามเกณฑ์.
  • ตัวดำเนินการเสริมเช่น AND, OR, DESC ถูกเรียกใช้บนวัตถุตัวสร้างเกณฑ์.
  • ชื่อฟิลด์นำมาจากวัตถุ ผ่าน get()ราก.