Introduktion til Criteria API
Der er to måder at skrive databaseforespørgsler på i Hibernate:
- Dvale forespørgselssprog
- Kriterier API
Du har allerede mødt den første for længe siden, det er tid til at stifte bekendtskab med Criteria API. Dette er et meget kraftfuldt værktøj, på et tidspunkt var det endnu mere populært end HQL. Nu er det ikke så populært mere, men til nogle opgaver vil det helt sikkert være en bedre løsning end HQL.
Under alle omstændigheder kan du ikke lære Hibernate uden at blive fortrolig med Criteria API. Lad os skrive et lille eksempel, og så analyserer vi det. For eksempel vil vi anmode alle medarbejdere (medarbejder) fra databasen. Her er hvad vi får:
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();
Ser kompliceret ud. Lad os skrive den samme HQL-forespørgsel til sammenligning:
String hqlQuery = "from Employee";
Query<Employee> query = session.createQuery(hqlQuery);
List<Employee> results = query.getResultList();
Bemærk, at de sidste to linjer i begge eksempler er næsten identiske: Vi opretter et Query-objekt og bruger det til at få en liste. Dette antyder, at resten af linjerne gør noget identisk.
Se på linje 3 og 4 i det første eksempel:
Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);
Lad os skrive dem på én linje:
critQuery.select(critQuery.from(Employee.class));
Minder det dig ikke om noget? Og hvis du farver det lidt anderledes:
critQuery.select(critQuery.from(Employee.class));
Ja, det er sådan en vanskelig konstruktion af SELECT FROM-forespørgslen.
Eksempler på arbejde med Criteria API
For en bedre forståelse vil jeg blot give et par eksempler.
Anmodning 1 . Få alle medarbejdere med en løn over 10.000:
critQuery.select(critQuery.from(Employee.class)).where(builder.gt(root.get("salary"), 10000));
Anmodning 2 . Få alle medarbejdere med en løn på mindre end 50 tusind:
critQuery.select(critQuery.from(Employee.class)).where(builder.lt(root.get("salary"), 50000));
Anmodning 3 . Få alle medarbejdere, hvis stillingsbetegnelse indeholder ordet "test":
critQuery.select(critQuery.from(Employee.class)).where(builder.like(root.get("occupation"), "%test%"));
Anmodning 4 . Få alle medarbejdere med en løn på 10 til 50 tusind:
critQuery.select(critQuery.from(Employee.class)).where(builder.between(root.get("salary"), 10000, 50000));
Anmodning 5 . Få alle medarbejdere, hvis navn er null:
critQuery.select(critQuery.from(Employee.class)).where(builder.isNull(root.get("name")));
Anmodning 6 . Få alle medarbejdere, hvis navn ikke er null:
critQuery.select(critQuery.from(Employee.class)).where(builder.isNotNull(root.get("name")));
Det er bare sådan en vanskelig måde at konstruere en forespørgsel på:
- Først får du genstandenCriteriaBuilder.
- Brug det derefter til at oprette et objektCriteriaQuery.
- Så begynder du at tilføje dele til den medCriteriaQueryOgCriteriaBuilder.
Sådan kan du indstille parametre for:
- VÆLG
- FRA
- HVOR
Bruger ogsåCriteriaBuilderdu kan konstruere forskellige betingelser for HVOR.
Avanceret arbejde med Criteria API
Ved hjælp af Criteria API kan du konstruere en forespørgsel af enhver kompleksitet. Og det er gode nyheder. For eksempel vil du have en kompleks WHERE-sætning. Sådan gør du:
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));
Hvis du vil skrive AND i stedet for OR, skal du kun ændre den sidste linje:
critQuery.select(critQuery.from(Employee.class)).where(builder.and(greaterThan, testers));
Alt er faktisk meget enkelt. Lad mig give dig en tabel med et par sammenligninger:
SQL | Metode | Fuld rekord |
---|---|---|
a<b | lt(a, b) | builder.lt(a, b) |
a > b | gt(a, b) | builder.gt(a, b) |
a ELLER b | eller(a,b) | bygmester.eller(a,b) |
a OG b | og (a,b) | bygmester.og(a,b) |
a LIKE b | som (a,b) | builder.like(a, b) |
a MELLEM (c, d) | mellem (a, c, d) | builder.between(a, c, d) |
a ER NULL | er Nul(a) | builder.isNull(a) |
a ER IKKE NULL | isNotNull(a) | builder.isNotNull(a) |
Alt er simpelt, er det ikke?
Og hvordan tilføjer vi sortering til forespørgslen? Meget simpelt:
critQuery.select( critQuery.from(Employee.class) );
critQuery.where( builder.and(greaterThan, testers) );
critQuery.orderBy( builder.asc(root.get("salary"), builder.desc(root.get("joinDate") )
Du kalder bare på objektetCriteriaQueryorderBy() -metoden og videregive de nødvendige parametre til den.
Sådan ser den samme forespørgsel ud i HQL. Sammenligne:
select * from Employee
where (…) and (…)
order by 'salary' asc, 'joinDate' desc
Du skal bare huske 3 ting:
- Nøgleoperatorer som SELECT, FROM, WHERE kaldes på et objektCriteriaQuery.
- Hjælpeoperatorer som AND, OR, DESC kaldes på objektetCriteriaBuilder.
- Feltnavne tages fra objektet via get()rod.
GO TO FULL VERSION