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.