ข้อมูลเบื้องต้นเกี่ยวกับ 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()ราก.