4.1 Parameter untuk permintaan

Hibernate membolehkan anda menghantar parameter kepada pertanyaan. Oleh itu, semua berfungsi dengan pertanyaan dan pangkalan data sangat dipermudahkan.

Sangat jarang untuk mencari pertanyaan yang tidak berubah. Pada mulanya, nampaknya anda hanya perlu mengembalikan senarai barangan dari pangkalan data. Dan kemudian ternyata anda memerlukan senarai produk terkini untuk pengguna tertentu pada tarikh tertentu. Diisih mengikut medan yang diperlukan, dan belum lagi senarai keseluruhan, tetapi halaman tertentu: contohnya, produk dari 21 hingga 30.

Dan inilah yang diselesaikan oleh pertanyaan berparameter. Anda menulis pertanyaan dalam HQL, dan kemudian anda menggantikan nilai yang boleh ditukar dengan "nama khas" - parameter. Dan kemudian secara berasingan apabila melaksanakan permintaan, anda boleh lulus nilai parameter ini.

Mari tulis pertanyaan HQL yang akan mengembalikan semua tugasan untuk pengguna dengan nama tertentu:

from EmployeeTask where employee.name = "Ivan Ivanovich"

Sekarang mari kita gantikan nama dengan parameter:

from EmployeeTask where employee.name = :username

Dan ini adalah bagaimana kod Java kami untuk mencari tugas akan kelihatan seperti:


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();

Selain itu, bukannya nama parameter, anda boleh menggunakan hanya nombor:


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();

Walaupun lebih baik, sudah tentu, menggunakan nama itu - lebih mudah untuk membaca dan mengekalkan kod tersebut.

4.2 kaedah setParameterList().

Terdapat juga kes apabila nilai parameter bukan satu, tetapi mewakili senarai objek. Sebagai contoh, kami ingin menyemak bahawa profesion pekerja terkandung dalam senarai tertentu.

Bagaimanakah ini boleh dilakukan:


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 jenis senarai boleh diluluskan sebagai nilai parameter:

  • tatasusunan objek: Objek[]
  • koleksi: Koleksi
  • tatasusunan ditaip: T[]
  • koleksi ditaip: Koleksi<T>

Jika anda memutuskan untuk lulus koleksi atau tatasusunan yang ditaip, maka anda perlu lulus jenis data sebagai parameter ketiga. Contoh:


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();

Apabila bekerja dengan parameter senarai, anda juga boleh menggunakan nombor dan bukannya nama parameter. Tetapi sekali lagi, nama itu lebih mudah.

4.3 Perlindungan terhadap SQL Injection

Salah satu tujuan terpenting parameter adalah untuk melindungi pangkalan data daripada suntikan SQL. Ramai pengaturcara baru, bukannya menggunakan parameter, hanya akan melekatkan rentetan beberapa bahagian.

Daripada menulis seperti ini:


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();

Akan menulis seperti ini:


String hql = "from EmployeeTask where employee.name = " + "Ivan Ivanovich";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
List<EmployeeTask> resultLIst = query.list();

Jangan sekali-kali berbuat demikian!Jangan sekali-kali melekatkan pertanyaan SQL/HQL daripada berbilang bahagian. Kerana lambat laun nama pengguna akan datang kepada anda daripada pelanggan. Dan penggodam jahat akan memberikan anda rentetan seperti""Ivan"; DROP TABLE user;"

Dan kemudian pertanyaan anda kepada pangkalan data akan mengambil bentuk:


from EmployeeTask where employee.name = "Ivan"; DROP TABLE user;

Dan masih bagus jika data anda dipadamkan begitu sahaja. Anda juga boleh menulis seperti ini:


from EmployeeTask where employee.name = "Ivan";
UPDATE user SET password = '1' WHERE user.role = 'admin'

Atau seperti ini:


from EmployeeTask where employee.name = "Ivan";
UPDATE user SET role = 'admin' WHERE user.id = 123;