Cuando trabajamos con bases de datos en Java usando Spring Data JPA, tarde o temprano aparece un problema:
¿Cómo construyo queries dinámicas sin escribir SQL a mano?
Ahí es donde entra el patrón Specification.
Una Specification<T> es básicamente un predicado tipado que se traduce a SQL.
Permite expresar condiciones de forma declarativa:
Specification<User> isAdult = (root, query, cb) ->
cb.greaterThanOrEqualTo(root.get("age"), 18);
Esto termina siendo:
WHERE age >= 18
Composición: el verdadero poder. Lo más interesante es que las specifications se pueden combinar:
Specification<User> isAdult = (root, query, cb) ->
cb.greaterThanOrEqualTo(root.get("age"), 18);
Specification<User> nameStartsWithA = (root, query, cb) ->
cb.like(root.get("name"), "A%");
Specification<User> combined =
isAdult.and(nameStartsWithA);
WHERE age >= 18 AND name LIKE 'A%'
Se puede usar en el dao o repositorio así:
List<User> result = userRepository.findAll(combined);
Simple, expresivo y reutilizable.
Ventajas:
- Queries dinámicas
- Composición (`and`, `or`)
- Tipado fuerte
- Evita strings SQL
Desventajas:
- Verboso (Criteria API no es linda)
- Poco intuitivo al principio
- Debug complicado
¿Qué está pasando por debajo?
Todo esto se apoya en JPA Criteria API
- No estás ejecutando código
- Estás construyendo un árbol de expresión (AST)
Por eso puede traducirse a SQL.
Specification es una forma poderosa de:
construir queries dinámicas, reutilizables y tipadas en Java
Pero… deja una pregunta interesante. ¿No podríamos hacer esto mismo con Streams?
Lo veremos en próximos posts ...

No hay comentarios.:
Publicar un comentario