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;