2.1 บทนำสู่คลาส Query

จุดสำคัญอีกประการหนึ่งคือคลาสตัวช่วยการค้นหา คุณสามารถดูได้จากตัวอย่างนี้:

public List<Employee> getAllEmployes() {
    try (Session session = sessionFactory.openSession()) {
            Query<Employee> query = session.createQuery("from Employee", Employee.class);
            return query.list();
    }
}

ในความเป็นจริง Query เป็นอินเทอร์เฟซและมีการใช้งานหลายอย่างสำหรับกรณีต่างๆ แต่เพื่อความง่าย ฉันจะเรียกมันว่าคลาสต่อไป นี่คือคลาสในความหมายกว้างๆ ในแง่ของ OOP

บันทึก. เคยมีสองคลาส:

  • แบบสอบถามเพื่ออธิบายแบบสอบถาม
  • TypedQueryเพื่ออธิบายแบบสอบถามด้วยประเภทที่รู้จัก

ปรากฏตัวครั้งแรกเมื่อไฮเบอร์เนตมีอยู่แล้วและยังไม่มีชื่อสามัญ จากนั้น หลังจากการเปิดตัว JDK 5 มีการเพิ่มคลาสอื่นใน Hibernate - TypedQuery ซึ่งรองรับการพิมพ์ผลลัพธ์ของคิวรีแล้ว

แต่เท่าที่ฉันจำได้ ตั้งแต่ Hibernate เวอร์ชันที่ 5 เหลือคลาสที่พิมพ์เพียงคลาสเดียว และตอนนี้เรียกว่า Query

วิธีมาตรฐานในการสร้าง Query คือ:


Query<Employee> query = session.createQuery("from Employee", Employee.class);

คุณได้เรียนรู้วิธีสร้างอ็อบเจกต์ Query แล้ว แต่คุณจะรัน Query เหล่านี้ได้อย่างไร

มันง่ายกว่าที่นี่ - เราเพิ่งเรียก เมธอด list()บนวัตถุ Query:


Query<Employee> query = session.createQuery("from Employee", Employee.class);
List<Employee> resultLіst = query.list();

เมธอดlist()มีคำเหมือน JPA เมธอดที่ทำสิ่งเดียวกัน แต่เรียกว่าgetResultList() บางครั้งคุณสามารถดูได้ในโค้ดที่เขียนโดยโปรแกรมเมอร์คนอื่นๆ

อย่างไรก็ตาม หากการสืบค้นบอกเป็นนัยว่าผลลัพธ์จะอยู่ในผลลัพธ์เดียว การเรียกใช้เมธอด uniqueResult()เพื่อเรียกการสืบค้นจะ ง่ายกว่า


Query<Employee> query = session.createQuery("from Employee where id = 1", Employee.class);
Employee result = query.uniqueResult();

เมธอดuniqueResult()มีคำเหมือน JPA, เมธอด singleResult( ) ได้รับการแนะนำสำหรับความเข้ากันได้ของ Hibernate กับมาตรฐาน JPA เขาทำสิ่งเดียวกันทุกประการ

2.2 เมธอดคลาสเคียวรี

จริงๆ แล้วคลาส Query มีเมธอดต่างๆ มากมาย ด้านล่างนี้ฉันจะพูดถึงอีกสามคน

วิธีแรกคือ วิธี การ stream( ) และคำพ้องความหมาย JPA getResultStream( )

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

ตัวอย่าง:


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
Stream<Employee> stream = query.stream();

วิธีที่สองคือวิธีexecuteUpdate() คุณสามารถเขียนแบบสอบถามที่จะเปลี่ยนแปลงบางอย่างในฐานข้อมูล ในกรณีนี้ จำเป็นอย่างยิ่งที่ไฮเบอร์เนตจะไม่ใช้ธุรกรรมแบบอ่านอย่างเดียวเมื่อเข้าถึงฐานข้อมูล

ตัวอย่างคำขอ: เราตัดสินใจที่จะยกระดับผู้ใช้ทั้งหมดขึ้น 1 ระดับ


Query<User> query = session.createQuery("update User set level=level+1", User.class);
int count = query.executeUpdate();

เมธอดexecuteUpdate()จะส่งคืนจำนวนแถวที่ได้รับการแก้ไขจริง

และสุดท้าย วิธีที่สามคือscroll( ) เราจะบอกคุณอีกเล็กน้อยเกี่ยวกับเรื่องนี้

2.3 วิธีการเลื่อนระดับ

วิธีการนี้ค่อนข้างคล้ายกับ วิธีการ stream ( ) มีเพียงให้คุณเลื่อนดูรายการผลลัพธ์โดยไม่ต้องดึงผลลัพธ์ออกมาเลย นั่นคือ คุณสามารถดำเนินการค้นหา จากนั้นเลื่อนไปยังบรรทัดที่ล้านของผลลัพธ์และเริ่มอ่านข้อมูลจากที่นั่น

ตัววนซ้ำขั้นสูงดังกล่าว


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
ScrollableResults<Employee> scroll = query.scroll();

วัตถุScrollableResultsมีวิธีการดังต่อไปนี้:

วิธี คำอธิบาย
รับ () ส่งกลับองค์ประกอบปัจจุบัน
ต่อไป() เลื่อนตัวชี้ไปยังองค์ประกอบถัดไป
ก่อนหน้า() เลื่อนตัวชี้ไปยังองค์ประกอบก่อนหน้า
เลื่อน (ขนาด int) เลื่อนไปข้างหน้าตามเส้นขนาด
ตำแหน่ง (ตำแหน่ง int) ทำให้องค์ประกอบ pos หมายเลของค์ประกอบปัจจุบัน
ล่าสุด() องค์ประกอบปัจจุบันเป็นองค์ประกอบสุดท้าย
อันดับแรก() องค์ประกอบปัจจุบันเป็นองค์ประกอบแรก
getRowNumber() ส่งกลับหมายเลขบรรทัดปัจจุบัน
setRowNumber() กำหนดหมายเลขบรรทัดปัจจุบัน

สมมติว่าคุณเรียกใช้คิวรีและต้องการรับองค์ประกอบสุดท้าย นี่คือวิธีการ:


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
ScrollableResults<Employee> scroll = query.scroll();
scroll.last();
Employee lastEmployee = scroll.get();