4.1 Parametri per le query

Hibernate ti consente di passare parametri alle query. Pertanto, tutti funzionano con le query e il database è notevolmente semplificato.

È molto raro trovare query immutabili. All'inizio sembra che tu debba solo restituire un elenco di merci dal database. E poi si scopre che hai bisogno di un elenco aggiornato di prodotti per un utente specifico in una data specifica. Ordinato per il campo richiesto, e non ancora l'intero elenco, ma una pagina specifica: ad esempio, prodotti da 21 a 30.

E questo è esattamente ciò che risolvono le query parametrizzate. Scrivi una query in HQL, quindi sostituisci i valori che possono essere modificati con "nomi speciali" - parametri. E poi separatamente durante l'esecuzione della richiesta, puoi passare i valori di questi parametri.

Scriviamo una query HQL che restituirà tutte le attività per un utente con un nome specifico:

from EmployeeTask where employee.name = "Ivan Ivanovich"

Ora sostituiamo il nome con un parametro:

from EmployeeTask where employee.name = :username

Ed ecco come apparirà il nostro codice Java per la ricerca di attività:


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

Inoltre, invece di un nome di parametro, puoi usare solo un numero:


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

Sebbene sia meglio, ovviamente, usare il nome, è molto più facile leggere e mantenere tale codice.

4.2 Metodo setParameterList().

Ci sono anche casi in cui il valore del parametro non è uno, ma rappresenta un elenco di oggetti. Ad esempio, vogliamo verificare che le professioni dei dipendenti siano contenute in un determinato elenco.

Come potrebbe essere fatto:


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 tipi di lista possono essere passati come valore di parametro:

  • matrice di oggetti: Oggetto[]
  • collezione: Collezione
  • matrice digitata: T[]
  • raccolta tipizzata: Collection<T>

Se decidi di passare una raccolta o un array tipizzato, devi passare il tipo di dati come terzo parametro. Esempio:


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

Quando si lavora con i parametri dell'elenco, è anche possibile utilizzare un numero al posto del nome del parametro. Ma ancora una volta, il nome è più conveniente.

4.3 Protezione contro SQL Injection

Uno degli scopi più importanti dei parametri è proteggere il database dalle iniezioni SQL. Molti programmatori alle prime armi, invece di utilizzare i parametri, incollerebbero semplicemente insieme una stringa di più parti.

Invece di scrivere così:


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

Scriverebbe così:


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

Non farlo mai!Non unire mai una query SQL/HQL da più parti. Perché prima o poi il nome utente ti arriverà dal client. E il malvagio hacker ti darà una stringa come""Ivan"; DROP TABLE user;"

E quindi la tua query al database assumerà la forma:


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

Ed è comunque positivo se i tuoi dati vengono semplicemente cancellati. Puoi anche scrivere così:


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

O così:


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