JavaRush /Курстар /All lectures for KY purposes /Параметрлүү сурамдар

Параметрлүү сурамдар

All lectures for KY purposes
Деңгээл , Сабак
жеткиликтүү

4.1 Сурамдар үчүн параметрлер

Hibernate сурамдарга параметрлерди өткөрүп берүүгө мүмкүнчүлүк берет. Ошентип, бардык сурам жана база менен иш аркандоо жеңилдейт.

Өтө сейрек өзгөрүлбөс сурамдарды кездештирүүгө болот. Башында, сага базадан бир гана товардын тизмесин жаңыртып койгондой сезилет. Бирок кийинчерээк белгилүү бир колдонуучу үчүн белгилүү бир датанын актуалдуу товаралардын тизмеси керек экендиги аныкталат. Керектүү талаа боюнча сорттолгон, жана бүт тизмеси дагы эмес, белгилүү бири бет: например, 21ден 30га чейинки товарлар.

Ошол учурда параметрлүү сурамдар бул маселени чечет. HQL сурамын жазасың, анан өзгөртүү мүмкүн болгон маанилерди “өзгөчө ысымдар” – параметрлерге алмаштырасың. Анан сурамды аткарганда, ошол параметрлердин маанилерин өзүнчө өткөрүп берүүгө болот.

Колдонуучунун белгилүү бир атына карата бардык тапшырмаларды кайтарган HQL сурамын жазалы:


from EmployeeTask where employee.name = "Иван Иванович"

Ал эми атын параметрге алмаштырабыз:


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", "Иван Иванович");
List<EmployeeTask> resultLIst = query.list();

Параметрдин орунуна жөн эле номерди колдоно аласың:


String hql = "from EmployeeTask where employee.name = :1";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
query.setParameter(1, "Иван Иванович");
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[] {"Программист", "Тестировщик"});
List<EmployeeTask> resultLIst = query.list();

Параметрдин мааниси катары 4 түрдөгү тизмени өткөрүп берүүгө болот:

  • объекттердин массиви: Object[]
  • жыйнак: Collection
  • типтештирилген массив: 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[] {"Программист", "Тестировщик"}, 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", "Иван Иванович");
List<EmployeeTask> resultLIst = query.list();

Төмөнкүчө жазышмак:


String hql = "from EmployeeTask where employee.name = " + "Иван Иванович";
Query<EmployeeTask> query = session.createQuery( hql, EmployeeTask.class);
List<EmployeeTask> resultLIst = query.list();

Муну эч качан кылба! SQL/HQL сурамын бир нече бөлүктөн курап койбо. Бир күнү, сенин колдонуучу досполочонун аты сага келип түшөт. Ошондо зыяндуу хакер колдонуучунун аты катары ""Иван"; DROP TABLE user;" жиберет.

Анда сенин базага сурооң ушундай болот:


from EmployeeTask where employee.name = "Иван"; DROP TABLE user;

Бул дагы жакшы, маалыматтарың өчүрүлүп калып жатат. Бирок төмөнкүдөй да жасаса болот:


from EmployeeTask where employee.name = "Иван";
UPDATE user SET password = '1' WHERE user.role = 'admin'

Же мындайча:


from EmployeeTask where employee.name = "Иван";
UPDATE user SET role = 'admin' WHERE user.id = 123;
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION