4.1 พารามิเตอร์สำหรับการร้องขอ
Hibernate อนุญาตให้คุณส่งพารามิเตอร์ไปยังแบบสอบถาม ดังนั้น การทำงานทั้งหมดกับแบบสอบถามและฐานข้อมูลจึงง่ายขึ้นอย่างมาก
การค้นหาข้อความค้นหาที่ไม่เปลี่ยนรูปนั้นหายากมาก ในตอนแรก ดูเหมือนว่าคุณเพียงแค่ต้องส่งคืนรายการสินค้าจากฐานข้อมูล จากนั้นปรากฎว่าคุณต้องการรายการผลิตภัณฑ์ล่าสุดสำหรับผู้ใช้เฉพาะในวันที่ระบุ จัดเรียงตามฟิลด์ที่ต้องระบุ แต่ยังไม่ใช่รายการทั้งหมด แต่จัดเรียงเฉพาะหน้า ตัวอย่างเช่น สินค้าตั้งแต่ 21 ถึง 30
และนี่คือสิ่งที่การสืบค้นแบบกำหนดพารามิเตอร์สามารถแก้ไขได้ คุณเขียนแบบสอบถามใน HQL แล้วแทนที่ค่าที่สามารถเปลี่ยนแปลงได้ด้วย "ชื่อพิเศษ" - พารามิเตอร์ จากนั้นแยกกันเมื่อดำเนินการตามคำขอคุณสามารถส่งค่าของพารามิเตอร์เหล่านี้ได้
มาเขียนแบบสอบถาม HQL ที่จะส่งคืนงานทั้งหมดสำหรับผู้ใช้ที่มีชื่อเฉพาะ:
from EmployeeTask where employee.name = "Ivan Ivanovich"
ตอนนี้เรามาแทนที่ชื่อด้วยพารามิเตอร์:
from EmployeeTask where employee.name = :username
และนี่คือลักษณะของโค้ด Java ของเราสำหรับการค้นหางาน:
String hql = "from EmployeeTask where employee.name = :username";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
query.setParameter("username", "Ivan Ivanovich");
List<EmployeeTask> resultLIst = query.list();
นอกจากนี้ แทนที่จะใช้ชื่อพารามิเตอร์ คุณสามารถใช้เพียงตัวเลข:
String hql = "from EmployeeTask where employee.name = :1";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
query.setParameter(1, "Ivan Ivanovich");
List<EmployeeTask> resultLIst = query.list();
แม้ว่าจะเป็นการดีกว่า แต่แน่นอนว่าการใช้ชื่อนั้นง่ายกว่ามากในการอ่านและบำรุงรักษาโค้ดดังกล่าว
4.2 เมธอด setParameterList()
นอกจากนี้ยังมีกรณีที่ค่าพารามิเตอร์ไม่ใช่ค่าเดียว แต่แสดงถึงรายการของวัตถุ ตัวอย่างเช่น เราต้องการตรวจสอบว่ามีอาชีพของพนักงานอยู่ในรายการใดรายการหนึ่ง
สิ่งนี้สามารถทำได้:
String hql = "from EmployeeTask where occupation IN (:occupation_list)";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
query.setParameterList("occupation_list", new String[] {"Programmer", "Tester"});
List<EmployeeTask> resultLIst = query.list();
สามารถส่งรายการ 4 ประเภทเป็นค่าพารามิเตอร์:
- อาร์เรย์ของวัตถุ: วัตถุ[]
- คอลเลกชัน: คอลเลกชัน
- อาร์เรย์ที่พิมพ์: T[]
- คอลเลกชันที่พิมพ์: Collection<T>
หากคุณตัดสินใจส่งคอลเล็กชันหรืออาร์เรย์ที่พิมพ์ คุณจะต้องส่งประเภทข้อมูลเป็นพารามิเตอร์ที่สาม ตัวอย่าง:
String hql = "from EmployeeTask where occupation IN (:occupation_list)";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
query.setParameterList("occupation_list", new String[] {"Programmer", "Tester"}, String.class);
List<EmployeeTask> resultLIst = query.list();
เมื่อทำงานกับพารามิเตอร์รายการ คุณสามารถใช้ตัวเลขแทนชื่อพารามิเตอร์ได้ แต่อีกครั้งชื่อสะดวกกว่า
4.3 การป้องกัน SQL Injection
วัตถุประสงค์ที่สำคัญที่สุดอย่างหนึ่งของพารามิเตอร์คือการปกป้องฐานข้อมูลจากการแทรก SQL โปรแกรมเมอร์มือใหม่หลายคน แทนที่จะใช้พารามิเตอร์ แทนที่จะใช้พารามิเตอร์ ก็แค่ติดสตริงของหลายส่วนเข้าด้วยกัน
แทนที่จะเขียนแบบนี้:
String hql = "from EmployeeTask where employee.name = :username";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
query.setParameter("username", "Ivan Ivanovich");
List<EmployeeTask> resultLIst = query.list();
จะเขียนแบบนี้
String hql = "from EmployeeTask where employee.name = " + "Ivan Ivanovich";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
List<EmployeeTask> resultLIst = query.list();
ไม่เคยทำอย่างนั้น!อย่ารวมคิวรี SQL/HQL จากหลายส่วนเข้าด้วยกัน เพราะไม่ช้าก็เร็วชื่อผู้ใช้จะมาหาคุณจากลูกค้า และแฮ็กเกอร์ที่ชั่วร้ายจะให้สตริงแก่คุณ""Ivan"; DROP TABLE user;"
จากนั้นแบบสอบถามของคุณไปยังฐานข้อมูลจะอยู่ในรูปแบบ:
from EmployeeTask where employee.name = "Ivan"; DROP TABLE user;
และยังเป็นการดีหากข้อมูลของคุณถูกลบออกไป คุณสามารถเขียนแบบนี้:
from EmployeeTask where employee.name = "Ivan";
UPDATE user SET password = '1' WHERE user.role = 'admin'
หรือแบบนี้:
from EmployeeTask where employee.name = "Ivan";
UPDATE user SET role = 'admin' WHERE user.id = 123;

GO TO FULL VERSION