Domanda

Quali sono i pro e i contro dell'utilizzo di Criteri o HQL ? L'API Criteria è un bel modo orientato agli oggetti per esprimere query in Hibernate, ma a volte le query Criteria sono più difficili da capire / costruire di HQL.

Quando usi i criteri e quando HQL? Cosa preferisci in quali casi d'uso? O è solo una questione di gusti?

È stato utile?

Soluzione

Preferisco principalmente le query sui criteri per le query dinamiche. Ad esempio, è molto più semplice aggiungere alcuni ordini in modo dinamico o lasciare fuori alcune parti (ad es. Restrizioni) a seconda di alcuni parametri.

D'altra parte sto usando HQL per query statiche e complesse, perché è molto più facile capire / leggere HQL. Inoltre, HQL è un po 'più potente, penso, ad es. per diversi tipi di join.

Altri suggerimenti

Esiste una differenza in termini di prestazioni tra HQL e criterioQuery, ogni volta che si esegue una query utilizzando criteriQuery, crea un nuovo alias per il nome della tabella che non si riflette nell'ultima cache interrogata per qualsiasi DB. Ciò comporta un sovraccarico di compilazione dell'SQL generato, impiegando più tempo per l'esecuzione.

Riguardo alle strategie di recupero [http://www.hibernate.org/315.html]

  
      
  • I criteri rispettano le impostazioni di pigrizia nelle tue mappature e garantiscono che venga caricato ciò che vuoi caricare. Ciò significa che una query Criteria potrebbe comportare diverse istruzioni SELECT immediate SQL per recuperare il sottografo con tutte le associazioni e le raccolte mappate non pigre. Se desideri modificare il " come " e persino il "quot" cosa "usa setFetchMode () per abilitare o disabilitare il recupero del join esterno per una particolare raccolta o associazione. Le query sui criteri rispettano anche completamente la strategia di recupero (join vs select vs subselect).
  •   
  • HQL rispetta le impostazioni di pigrizia nelle tue mappature e garantisce che venga caricato ciò che vuoi caricare. Ciò significa che una query HQL potrebbe comportare diverse istruzioni SELECT immediate SQL per recuperare il sottografo con tutte le associazioni e le raccolte mappate non pigre. Se desideri modificare il " come " e persino il "quot", utilizzare LEFT JOIN FETCH per abilitare il recupero dei join esterni per una particolare raccolta o un'associazione molti-a-uno o uno-a-uno nullable, o JOIN FETCH per abilitare il recupero dei join interni per un non-nullable associazione molti-a-uno o uno-a-uno. Le query HQL non rispettano alcun fetch = " join " definito nel documento di mappatura.
  •   

Criteri è un'API orientata agli oggetti, mentre HQL significa concatenazione di stringhe. Ciò significa che si applicano tutti i vantaggi dell'orientamento agli oggetti:

  1. A parità di altre condizioni, la versione OO è leggermente meno soggetta a errori. Qualsiasi vecchia stringa potrebbe essere aggiunta alla query HQL, mentre solo gli oggetti Criteria validi possono trasformarla in una struttura Criteria. In effetti, le classi Criteria sono più vincolate.
  2. Con il completamento automatico, l'OO è più rilevabile (e quindi più facile da usare, almeno per me). Non è necessario necessariamente ricordare quali parti della query vanno dove; l'IDE può aiutarti
  3. Inoltre, non è necessario ricordare i dettagli della sintassi (come i simboli dove vanno). Tutto quello che devi sapere è come chiamare metodi e creare oggetti.

Poiché HQL è molto simile a SQL (che la maggior parte degli sviluppatori conosce già molto bene), questi "non devono ricordare" gli argomenti non hanno lo stesso peso. Se HQL fosse più diverso, sarebbe più importante.

Di solito utilizzo i criteri quando non so quali input verranno utilizzati su quali dati. Come in un modulo di ricerca in cui l'utente può inserire da 1 a 50 voci e non so cosa cercheranno. È molto semplice aggiungere di più ai criteri mentre cerco ciò che l'utente sta cercando. Penso che sarebbe un po 'più problematico mettere una query HQL in quella circostanza. HQL è fantastico anche se so esattamente cosa voglio.

HQL è molto più facile da leggere, più facile da eseguire il debug usando strumenti come il plugin Eclipse Hibernate e più facile da registrare. Le query con criteri sono migliori per la creazione di query dinamiche in cui gran parte del comportamento è determinato in fase di esecuzione. Se non conosci SQL, potrei capire usando le query Criteria, ma nel complesso preferisco HQL se so cosa voglio in anticipo.

I criteri sono l'unico modo per specificare ricerche di chiavi naturali che sfruttano la speciale ottimizzazione nella cache delle query di secondo livello. HQL non ha alcun modo per specificare il suggerimento necessario.

Puoi trovare qualche informazione in più qui:

Il criterio Api è uno dei buoni concetti di Hibernate. a mio avviso, questi sono i pochi punti in cui possiamo fare la differenza tra HQL e Criteri Api

  1. HQL deve eseguire operazioni di selezione e non selezione sui dati, ma i criteri sono solo per la selezione dei dati, non possiamo eseguire operazioni di non selezione usando i criteri.
  2. HQL è adatto per l'esecuzione di query statiche, dove come criteri è adatto per l'esecuzione di query dinamiche
  3. HQL non supporta il concetto impaginazione , ma possiamo ottenere l'impaginazione con i criteri.
  4. I criteri impiegavano più tempo per l'esecuzione rispetto a HQL.
  5. Con Criteria siamo al sicuro con Iniezione SQL a causa della sua generazione dinamica di query ma in HQL poiché le tue query sono fisse o parametrizzate, non c'è sicurezza da SQL Injection

Per me i criteri sono abbastanza facili da capire e fare query dinamiche. Ma il difetto che dico finora è che carica tutte le relazioni di molti uno ecc. Perché abbiamo solo tre tipi di FetchModes cioè Select, Proxy e Default e in tutti questi casi carica molti uno (potrebbe essere sbagliato se così aiuto me :) :)

Il secondo problema con Criteria è che carica un oggetto completo, cioè se voglio solo caricare EmpName di un dipendente, non verrà fornito con questo istinto, verrà fornito con l'oggetto Employee completo e posso ottenere EmpName da esso grazie a questo funziona davvero male nei rapporti . dove appena HQL ha caricato (non ha caricato associazione / relazioni) ciò che si desidera così aumentare le prestazioni molte volte.

Una caratteristica di Criteria è che ti proteggerà da SQL Injection a causa della sua generazione dinamica di query dove, come in HQL, le tue query sono fisse o parametrizzate, quindi non sono sicure da SQL Injection.

Anche se scrivi HQL nei tuoi file aspx.cs, sei strettamente associato al tuo DAL.

Nel complesso la mia conclusione è che ci sono posti in cui non puoi vivere senza HQL come i rapporti, quindi usali altrimenti I criteri sono più facili da gestire.

Per utilizzare il meglio dei due mondi, l'espressività e la concisione di HQL e la natura dinamica dei criteri considerano l'utilizzo di Querydsl .

Querydsl supporta JPA / Hibernate, JDO, SQL e Collections.

Sono il manutentore di Querydsl, quindi questa risposta è parziale.

Per me la più grande vittoria su Criteria è l'API di esempio, in cui è possibile passare un oggetto e l'ibernazione costruirà una query basata su tali proprietà dell'oggetto.

Oltre a ciò, i criteri API hanno le sue stranezze (credo che il team di ibernazione stia rielaborando l'API), come:

  • a criterio.createAlias ??(" obj ") forza un join interno anziché un possibile join esterno
  • non puoi creare lo stesso alias due volte
  • alcune clausole sql non hanno una controparte con criteri semplici (come una sottoselezione)
  • ecc.

Tendo a utilizzare HQL quando desidero query simili a sql (elimina da Utenti dove status = 'bloccato') e tendo a utilizzare i criteri quando non desidero utilizzare l'aggiunta di stringhe.

Un altro vantaggio di HQL è che puoi definire tutte le tue domande in anticipo e persino esternalizzarle in un file o giù di lì.

L'API dei criteri è più adatta per le query generate dinamicamente quando i filtri di query vengono applicati in modo dinamico in fase di esecuzione. Pertanto, per prevenire SQL Attacchi di iniezione durante la creazione di query dinamiche, Criteria API è un'ottima scelta.

Le query sui criteri sono meno espressive e si può facilmente finire con un query generata da SQL . Una volta mi sono unito a una grande applicazione aziendale in cui l'API Criteria era il metodo di query predefinito e nemmeno una revisione approfondita del codice poteva superare l'orrore di non sapere con quali query SQL avremmo finito.

JPQL o HQL è molto più espressivo ed è molto più semplice prevedere la query SQL generata associata. È anche molto più facile rivedere le proprie query HQL rispetto a quelle di Criteria.

La maggior parte dei casi d'uso per le query di entità non richiedono clausole dinamiche, pertanto è possibile implementare la maggior parte delle query con JPQL lasciando criteri per quelli dinamici.

Vale la pena notare che la selezione di entità con JPQL o API Criteria ha senso se è necessario modificarle. Altrimenti, una proiezione DTO funziona meglio. Consulta questo articolo per ulteriori informazioni .

I criteri api forniscono una caratteristica distinta che né SQL né HQL forniscono. vale a dire. consente il controllo del tempo di compilazione di una query.

Abbiamo utilizzato principalmente i criteri nella nostra applicazione all'inizio, ma dopo che è stato sostituito con HQL a causa di problemi di prestazioni.
Principalmente stiamo usando query molto complesse con diversi join che portano a più query in Criteria ma sono molto ottimizzate in HQL.
Il caso è che usiamo solo diverse proprietà su oggetti specifici e non su oggetti completi. Con Criteria il problema era anche la concatenazione di stringhe.
Diciamo che se è necessario visualizzare il nome e il cognome dell'utente in HQL è abbastanza semplice (nome || '' || cognome) ma in Crteria questo non è possibile.
Per ovviare a questo problema abbiamo usato i risultatiTransormer, dove c'erano metodi in cui tale concatenazione era implementata per il risultato necessario.
Oggi usiamo principalmente HQL in questo modo:

String hql = "select " +
            "c.uuid as uuid," +
            "c.name as name," +
            "c.objective as objective," +
            "c.startDate as startDate," +
            "c.endDate as endDate," +
            "c.description as description," +
            "s.status as status," +
            "t.type as type " +
            "from " + Campaign.class.getName() + " c " +
            "left join c.type t " +
            "left join c.status s";

Query query =  hibernateTemplate.getSessionFactory().getCurrentSession().getSession(EntityMode.MAP).createQuery(hql);
query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
return query.list();

quindi nel nostro caso i record restituiti sono mappe delle proprietà necessarie.

  • HQL deve eseguire operazioni di selezione e non selezione sui dati, ma i criteri sono solo per la selezione dei dati, non possiamo eseguire operazioni di non selezione usando i criteri
  • HQL è adatto per l'esecuzione di query statiche, dove come criteri è adatto per l'esecuzione di query dinamiche
  • HQL non supporta il concetto di impaginazione, ma possiamo ottenere l'impaginazione con i criteri
  • I criteri impiegavano più tempo per l'esecuzione di HQL
  • Con Criteria siamo al sicuro con SQL Injection a causa della sua generazione dinamica di query ma in HQL poiché le tue query sono fisse o parametrizzate, non c'è sicurezza da SQL Injection.

source

Query di criteri per dinamicamente possiamo costruire query in base ai nostri input .. Nel caso di query Hql è la query statica una volta che abbiamo costruito non possiamo cambiare la struttura della query.

Non voglio calciare un cavallo morto qui, ma è importante menzionare che le query dei criteri sono ora deprecate. Usa HQL.

Preferisco anche le query dei criteri per le query dinamiche. Ma preferisco hql per le query di eliminazione, ad esempio se elimina tutti i record dalla tabella figlio per l'id padre 'xyz', è facilmente raggiungibile da HQL, ma per i criteri API prima dobbiamo attivare n numero di query di eliminazione dove n è il numero di figlio record di tabella.

La maggior parte delle risposte qui sono fuorvianti e menzionano che Domande sui criteri sono più lente di HQL , il che in realtà non è il caso.

Se approfondisci ed esegui alcuni test, vedrai Le query sui criteri funzionano molto meglio del normale HQL .

E anche con Query sui criteri ottieni Controllo orientato agli oggetti che non è presente con HQL .

Per ulteriori informazioni leggi questa risposta qui .

C'è un altro modo. Ho finito con la creazione di un parser HQL basato sulla sintassi originale in ibernazione, in modo che prima analizzasse l'HQL, quindi potesse iniettare dinamicamente i parametri dinamici o aggiungere automaticamente alcuni filtri comuni per le query HQL. Funziona benissimo!

Questo post è piuttosto vecchio. La maggior parte delle risposte parla di criteri di ibernazione, non di criteri JPA. JPA 2.1 ha aggiunto CriteriaDelete / CriteriaUpdate e EntityGraph che controlla esattamente cosa recuperare. L'API dei criteri è migliore poiché Java è OO. Ecco perché viene creato l'APP. Quando viene compilato, JPQL verrà tradotto in albero AST (modello OO) prima di essere tradotto in SQL.

HQL può causare problemi di sicurezza come SQL injection.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top