Spring Boot JPA Fetch Type ความต่างระหว่าง EAGER Loading VS LAZY Loading
Spring Boot JPA มี Fetch Type สองแบบที่ใช้ในการโหลดข้อมูลจากฐานข้อมูล คือ EAGER Loading และ LAZY Loading
EAGER Loading คือการโหลดข้อมูลทั้งหมดของ entity ที่เกี่ยวข้องในเวลาเดียวกัน เมื่อเรียกใช้งาน entity หลัก นั่นคือ entity หลักจะโหลดข้อมูลที่เกี่ยวข้องทั้งหมดมาในครั้งเดียว เป็นวิธีที่สะดวกแต่อาจทำให้เกิดปัญหาการโหลดข้อมูลที่ไม่จำเป็นตามมาได้

LAZY Loading คือการโหลดข้อมูลเมื่อมีการเรียกใช้งาน entity ที่เกี่ยวข้องจริงๆ ในเวลาที่จำเป็นเท่านั้น เมื่อเรียกใช้งาน entity หลัก ข้อมูลที่เกี่ยวข้องจะไม่ถูกโหลดมาในครั้งนั้น แต่จะถูกโหลดเมื่อมีการเข้าถึงข้อมูลเหล่านั้นจริงๆ นั่นคือ entity หลักจะไม่มีความรับผิดชอบในการโหลดข้อมูลที่เกี่ยวข้อง วิธีนี้ช่วยลดการโหลดข้อมูลที่ไม่จำเป็นและเพิ่มประสิทธิภาพในการเรียกใช้งาน
การเลือกใช้ Fetch Type ขึ้นอยู่กับกรณีการใช้งาน หากต้องการโหลดข้อมูลที่เกี่ยวข้องทั้งหมดในครั้งเดียว สะดวกและไม่มีปัญหาเรื่องประสิทธิภาพ ควรใช้ EAGER Loading แต่หากต้องการลดการโหลดข้อมูลที่ไม่จำเป็นและมีประสิทธิภาพในการเรียกใช้งาน ควรใช้ LAZY Loading
ตัวอย่างการใช้ Fetch Type แบบ LAZY 🫠

โดยเราจะให้ ProductInventoryEntity นั้น join เข้ากับ ProductEntity แบบ OneToOne ด้วยคุณสมบัติของ LAZY loading ก็จะไม่ดึงข้อมูลของ ProductEntity ออกมา จะดึงเพราะแค่ ProductInventoryEntity เท่านั้น
ถ้าเทียบกับ SQL ก็จะประมาณนี้
SELECT * FROM product_inventory WHERE product_id = '1';

มาดูผลลัพธ์กัน

เป็นไปตามคาดดึงแค่ข้อมูลใน ProductInventoryEntity ตัวเดียวจริงๆ แล้วเมื่อไหร่ล่ะที่ LAZY load จะทำการดึงข้อมูลของ table ที่ทำการ join เอาไว้ ……. ก็ต้องเมื่อมีการเรียกใช้ไง งั้นเรามาลองเรียกใช้กันจะได้รู้ว่าทำการดึงข้อมูลตอนไหน

เราก็ทำให้มีการเรียกใช้ในส่วนของ ProductEntity มาดูกัน!!!

เรียบร้อยมีการดึงข้อมูล productEntity แล้ววว
ตัวอย่างการใช้ Fetch Type แบบ EAGER


เดี๋ยวเอาส่วนที่เรียกใช้ที่ service ออก แค่ findById ตรงๆ แล้ว log เลย

ถ้าดูจาก log ก็จะเห็นว่าข้อมูลของ ProductEntity ออกมาเห็บไว้ให้เลย โดยที่เราไม่ต้องเรียกใช้ก็ได้
เปรียบเทียบข้อดี ข้อเสีย ของ EAGER Loading VS LAZY Loading
- EAGER Loading:
- ข้อดี:
- โหลดข้อมูลที่เกี่ยวข้องครบถ้วนทุกครั้ง ทำให้สามารถเข้าถึงข้อมูลที่เกี่ยวข้องได้โดยตรงและรวดเร็ว
- ไม่เกิดปัญหาการโหลดข้อมูลที่ล่าช้าเนื่องจากการเข้าถึงข้อมูลที่เกี่ยวข้อง
- ข้อเสีย:
- การโหลดข้อมูลที่ไม่จำเป็นอาจทำให้มีการใช้ทรัพยากรในระบบมากขึ้น
- บางครั้งอาจเกิดการโหลดข้อมูลที่ไม่จำเป็นมากเกินไป ทำให้ระบบทำงานช้าลง
- ข้อดี:
- LAZY Loading:
- ข้อดี:
- ประหยัดทรัพยากรในการโหลดข้อมูลเนื่องจากจะโหลดข้อมูลเมื่อจำเป็นเท่านั้น
- ช่วยลดเวลาในการโหลดข้อมูลเมื่อไม่มีความจำเป็น
- ข้อเสีย:
- อาจเกิดปัญหาการโหลดข้อมูลที่ล่าช้าเมื่อมีการเข้าถึงข้อมูลที่เกี่ยวข้อง
- การเข้าถึงข้อมูลที่เกี่ยวข้องอาจต้องใช้การโหลดเพิ่มเติม ซึ่งอาจทำให้ระบบทำงานช้าลง
- ข้อดี:
แล้วถ้าเราไม่ Fetch Type ให้ล่ะ Default จะเป็นอะไร ?

Default fetch type ใน JPA :
- สำหรับการสัมพันธ์แบบ single-valued (เช่น
@OneToOne,@ManyToOne): Default fetch type คือFetchType.EAGERนั่นหมายความว่าโดยค่าเริ่มต้น ในกรณีที่คุณดึง entity ที่หนึ่ง ตัว JPA จะทำการดึงข้อมูลของ entity ที่เกี่ยวข้องด้วย - สำหรับการสัมพันธ์แบบ collection-valued (เช่น
@OneToMany,@ManyToMany): Default fetch type คือFetchType.LAZYนั่นหมายความว่าโดยค่าเริ่มต้น ในกรณีที่คุณดึง entity ตัว JPA จะทำการดึงข้อมูลของ collection ที่เกี่ยวข้องด้วย
หวังว่าข้อมูลเรื่องนี้จะเป็นประโยชน์ช่วยให้คนที่เริ่มศึกษาตัว Spring boot , JPA หรือ คนที่อยากรู้เพิ่มเติมนะครับ แล้วจะมาแชร์ข้อมูลใหม่เมื่อ…………