Introduzione all'API dei criteri

Esistono due modi per scrivere query di database in Hibernate:

  • Linguaggio di query di ibernazione
  • API dei criteri

Hai già incontrato il primo molto tempo fa, è tempo di familiarizzare con l'API Criteria. Questo è uno strumento molto potente, a un certo punto era persino più popolare di HQL. Ora non è più così popolare, ma per alcune attività sarà sicuramente una soluzione migliore di HQL.

In ogni caso, non puoi imparare Hibernate senza familiarizzare con l'API Criteria. Scriviamo un piccolo esempio e poi lo analizzeremo. Ad esempio, richiederemo tutti i dipendenti (dipendente) dal database. Ecco cosa otterremo:

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Employee> critQuery = builder.createQuery(Employee.class);

Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);

Query<Employee> query = session.createQuery(critQuery);
List<Employee> results = query.getResultList();

Sembra complicato. Scriviamo la stessa query HQL per il confronto:

String hqlQuery = "from Employee";

Query<Employee> query = session.createQuery(hqlQuery);
List<Employee> results = query.getResultList();

Si noti che le ultime due righe di entrambi gli esempi sono quasi identiche: creiamo un oggetto Query e lo usiamo per ottenere una lista. Questo suggerisce che il resto delle linee sta facendo qualcosa di identico.

Guarda le righe 3 e 4 del primo esempio:

Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);

Scriviamoli in una riga:

critQuery.select(critQuery.from(Employee.class));

Non ti ricorda niente? E se lo colori in modo leggermente diverso:

critQuery.select(critQuery.from(Employee.class));

Sì, questa è una costruzione così complicata della query SELECT FROM.

Esempi di utilizzo dell'API Criteria

Per una migliore comprensione, mi limiterò a fornire alcuni esempi.

Richiesta 1 . Ottieni tutti i dipendenti con uno stipendio superiore a 10 mila:

critQuery.select(critQuery.from(Employee.class)).where(builder.gt(root.get("salary"), 10000));

Richiesta 2 . Ottieni tutti i dipendenti con uno stipendio inferiore a 50 mila:

critQuery.select(critQuery.from(Employee.class)).where(builder.lt(root.get("salary"), 50000));

Richiesta 3 . Ottieni tutti i dipendenti il ​​cui titolo di lavoro contiene la parola "test":

critQuery.select(critQuery.from(Employee.class)).where(builder.like(root.get("occupation"), "%test%"));

Richiesta 4 . Ottieni tutti i dipendenti con uno stipendio da 10 a 50 mila:

critQuery.select(critQuery.from(Employee.class)).where(builder.between(root.get("salary"), 10000, 50000));

Richiesta 5 . Ottieni tutti i dipendenti il ​​cui nome è nullo:

critQuery.select(critQuery.from(Employee.class)).where(builder.isNull(root.get("name")));

Richiesta 6 . Ottieni tutti i dipendenti il ​​cui nome non è nullo:

critQuery.select(critQuery.from(Employee.class)).where(builder.isNotNull(root.get("name")));

È solo un modo così complicato per costruire una query:

  • Per prima cosa ottieni l'oggettoCriteriaBuilder.
  • Quindi usalo per creare un oggettoCriteriQuery.
  • Quindi inizi ad aggiungere parti ad esso conCriteriQueryECriteriaBuilder.

Ecco come puoi impostare i parametri per:

  • SELEZIONARE
  • DA
  • DOVE

Usando ancheCriteriaBuilderpuoi costruire diverse condizioni per WHERE.

Lavoro avanzato con Criteria API

Utilizzando l'API Criteria, puoi costruire una query di qualsiasi complessità. E questa è una grande notizia. Ad esempio, vuoi una clausola WHERE complessa. Ecco come farlo:

Predicate greaterThan = builder.gt(root.get("salary"), 1000);
Predicate testers = builder.like(root.get("occupation"), "test%");

critQuery.select(critQuery.from(Employee.class)).where(builder.or(greaterThan, testers));

Se vuoi scrivere AND invece di OR, devi solo cambiare l'ultima riga:

critQuery.select(critQuery.from(Employee.class)).where(builder.and(greaterThan, testers));

Tutto è in realtà molto semplice. Lascia che ti dia una tabella con alcuni confronti:

SQL Metodo Registro completo
un<b lt(a, b) costruttore.lt(a, b)
un > b gt(a, b) costruttore.gt(a, b)
a O b o (a, b) costruttore.o(a, b)
a E b e (a,b) costruttore.e(a,b)
un MI PIACE b come (a,b) builder.like(a, b)
a TRA (c, d) tra (a, c, d) builder.tra (a, c, d)
a È NULLA èNull(a) builder.isNull(a)
a NON È NULLA isNotNull(a) builder.isNotNull(a)

Tutto è semplice, non è vero?

E come aggiungiamo l'ordinamento alla query? Molto semplice:

critQuery.select( critQuery.from(Employee.class) );
critQuery.where( builder.and(greaterThan, testers) );
critQuery.orderBy( builder.asc(root.get("salary"), builder.desc(root.get("joinDate") )

Basta chiamare l'oggettoCriteriQueryorderBy() metodo e passargli i parametri richiesti.

Ecco come apparirebbe la stessa query in HQL. Confrontare:

select * from Employee
where (…) and (…)
order by 'salary' asc, 'joinDate' desc

Devi solo ricordare 3 cose:

  • Operatori chiave come SELECT, FROM, WHERE vengono chiamati su un oggettoCriteriQuery.
  • Operatori ausiliari come AND, OR, DESC vengono chiamati sull'oggettoCriteriaBuilder.
  • I nomi dei campi sono presi dall'oggetto tramite get()radice.