Ci-dessous, plusieurs exemples qui reprennent l’ensemble des deux pages précédentes
WHERE avec API Criteria
Et finalement une autre option est d’utiliser l’API Criteria
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);
Root<Pet> pet = cq.from(Pet.class);
Join<Pet, Owner> owner = pet.join("owner");
cq.select(pet)
.where(
cb.equal(pet.get("type"), "dog"),
cb.lessThan(pet.get("age"), 5),
cb.equal(owner.get("id"), ownerId)
)
.orderBy(cb.asc(pet.get("name")));
TypedQuery<Pet> q = em.createQuery(cq);
List<Pet> filteredPets = q.getResultList();- La construction de la requête est modulaire et peut être facilement étendue ou modifiée.
- Les performances sont généralement meilleures car la requête est optimisée par le fournisseur JPA.
Résultat Un seul appel SQL
[Hibernate]
select
p1_0.id,
p1_0.age,
p1_0.name,
p1_0.owner_id,
p1_0.type
from
pets p1_0
where
p1_0.type=?
and p1_0.age<?
and p1_0.owner_id=?
order by
p1_0.nameJOIN
Ainsi, si nous souhaitons à la fois charger les animaux et les propriétaires en une seule requête nous pouvons utiliser le JOIN FETCH
Long ownerId = 1L; // Replace with the actual owner ID
String jpql = "SELECT p FROM Pet p JOIN FETCH p.owner WHERE p.type = :type AND p.age < :age AND p.owner.id = :ownerId ORDER BY p.name ASC";
TypedQuery<Pet> query = em.createQuery(jpql, Pet.class);
query.setParameter("type", "dog");
query.setParameter("age", 5);
query.setParameter("ownerId", ownerId);
List<Pet> filteredPets = query.getResultList();
// Display results
filteredPets.forEach(System.out::println);
filteredPets.forEach(pet -> {
System.out.println(pet.getOwner().getName());
});Résultat
Lors du pet.getOwner().getName() le propriétaire est déjà chargé
[Hibernate]
select
p1_0.id,
p1_0.age,
p1_0.name,
p1_0.owner_id,
o1_0.id,
o1_0.name,
p1_0.type
from
pets p1_0
join
owners o1_0
on o1_0.id = p1_0.owner_id
where
p1_0.type = ?
and p1_0.age < ?
and p1_0.owner_id = ?
order by
p1_0.name
Exemple update
Attention
À toujours exécuter le code dans une transaction
// Start a transaction
em.getTransaction().begin();
// Create CriteriaBuilder and CriteriaUpdate
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaUpdate<Pet> update = cb.createCriteriaUpdate(Pet.class);
// Define the root entity (Pet)
Root<Pet> pet = update.from(Pet.class);
// Join with Owner
Join<Pet, Owner> owner = pet.join("owner");
// Set the update: increase age by 1
update.set(pet.get("age"), cb.sum(pet.get("age"), 1))
.where(
cb.equal(pet.get("type"), "dog"),
cb.lessThan(pet.get("age"), 5),
cb.equal(owner.get("id"), ownerId)
);
// Execute the update
Query query = em.createQuery(update);
int updatedCount = query.executeUpdate();
// Commit transaction
em.getTransaction().commit();