4.1 İstekler için parametreler

Hazırda bekletme, parametreleri sorgulara geçirmenize olanak tanır. Böylece, tüm sorgular ve veritabanı ile çalışmak büyük ölçüde basitleştirilmiştir.

Değişmez sorgular bulmak çok nadirdir. İlk başta, veritabanından bir mal listesi döndürmeniz yeterli gibi görünüyor. Ve sonra, belirli bir tarihte belirli bir kullanıcı için güncel bir ürün listesine ihtiyacınız olduğu ortaya çıktı. Gerekli alana ve henüz tüm listeye değil, belirli bir sayfaya göre sıralanmıştır: örneğin, 21'den 30'a kadar olan ürünler.

Ve bu tam olarak parametreleştirilmiş sorguların çözdüğü şeydir. HQL'de bir sorgu yazarsınız ve ardından değiştirilebilecek değerleri "özel adlar" - parametrelerle değiştirirsiniz. Ve sonra, isteği yürütürken ayrı ayrı, bu parametrelerin değerlerini iletebilirsiniz.

Belirli bir ada sahip bir kullanıcı için tüm görevleri döndürecek bir HQL sorgusu yazalım:

from EmployeeTask where employee.name = "Ivan Ivanovich"

Şimdi adı bir parametre ile değiştirelim:

from EmployeeTask where employee.name = :username

Görevleri bulmak için Java kodumuz şöyle görünecek:


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

Ayrıca, parametre adı yerine yalnızca bir sayı kullanabilirsiniz:


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

Elbette adı kullanmak daha iyi olsa da, bu tür bir kodu okumak ve sürdürmek çok daha kolaydır.

4.2 setParameterList() yöntemi.

Parametre değerinin bir olmadığı, ancak bir nesne listesini temsil ettiği durumlar da vardır. Örneğin, çalışanların mesleklerinin belirli bir listede yer alıp almadığını kontrol etmek istiyoruz.

Bu nasıl yapılabilir:


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 tip liste parametre değeri olarak iletilebilir:

  • nesne dizisi: Nesne[]
  • koleksiyon: Koleksiyon
  • yazılan dizi: T[]
  • yazılan koleksiyon: Collection<T>

Yazılı bir koleksiyonu veya diziyi iletmeye karar verirseniz, üçüncü parametre olarak veri tipini iletmeniz gerekir. Örnek:


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

Liste parametreleriyle çalışırken, parametre adı yerine bir sayı da kullanabilirsiniz. Ama yine de, isim daha uygun.

4.3 SQL Enjeksiyonuna Karşı Koruma

Parametrelerin en önemli amaçlarından biri veritabanını SQL enjeksiyonlarından korumaktır. Pek çok acemi programcı, parametre kullanmak yerine birkaç parçadan oluşan bir diziyi birbirine yapıştırır.

Böyle yazmak yerine:


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

Şöyle yazardım:


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

Bunu asla yapma!Birden çok parçadan oluşan bir SQL/HQL sorgusunu asla birbirine bağlamayın. Çünkü er ya da geç kullanıcı adı size müşteriden gelecektir. Ve kötü bilgisayar korsanı size şöyle bir dize verecek""Ivan"; DROP TABLE user;"

Ve sonra veritabanına sorgunuz şu şekli alacaktır:


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

Verilerinizin basitçe silinmesi yine de iyidir. Şu şekilde de yazabilirsiniz:


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

Veya bunun gibi:


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