Tengo la siguiente consulta de requisitos:
"/artículo? categoría =cocina& categoría =deportes"
Esta consulta funciona sin enlaces personalizados. Me dará todos los artículos de Cocina y deportes como Respuesta. Está haciendo una operación OR de alguna manera.
Pero necesito personalizar el enlace porque necesito ignorar el caso. Ahora estoy usando este enlace personalizado:
@Repository public interface ArticleRepository extends JpaRepository<Article, Long>, QueryDslPredicateExecutor<QArticle>, QuerydslBinderCustomizer<QArticle> { @Override default public void customize(QuerydslBindings bindings, QArticle article) { bindings.bind(String.class).first((StringPath path, String value) -> path.containsIgnoreCase(value)); } }Esto solo filtra el primer valor disponible de un atributo. Entonces, en este caso, solo da artículos en la categoría cocina como Respuesta. El segundo valor de la categoría (deportes) se ignora.
Y ahora mi pregunta: ¿Cómo puedo obtener los artículos de ambas categorías ignorando el sentido de mayúsculas y minúsculas? ¿Qué necesito cambiar en mi enlace personalizado para lograr eso?
Muchísimas gracias
QuerydslBindings.TypeBinder#first utiliza un enlace de valor único . Debe usar QuerydslBindings.TypeBinder# all . Este método opera en un enlace multivalor .
Proporcioné varios ejemplos de cómo personalizar sus enlaces en esta respuesta . Algo como esto debería funcionar para usted:
@Override default public void customize(QuerydslBindings bindings, QArticle article) { // using explicit path bindings bindings.bind(article.category).all((path, values) -> { BooleanBuilder predicate = new BooleanBuilder(); // with a for loop for (String value : values) { predicate.or(path.containsIgnoreCase(value)); } }); // using a type binding bindings.bind(String.class).all((StringPath path, Collection<? extends String> values) -> { BooleanBuilder predicate = new BooleanBuilder(); // oneliner with Java 8 forEach values.forEach( value -> predicate.or(path.containsIgnoreCase(value) ); }); }Los enlaces correctos para su propiedad article.category deberían ser así:
bindings.bind(article.category).all((path, value) -> { BooleanBuilder predicate = new BooleanBuilder(); value.forEach(o -> predicate.or(path.equalsIgnoreCase(o))); return Optional.of(predicate); });Si no necesita ninguna manipulación de los parámetros (como ignorar el caso), puede simplificarlo a eso:
bindings.bind(article.category).all((path, value) -> Optional.of(path.in(value)));Después de una buena búsqueda encontré la solución.
bindings.bind(String.class).all(new MultiValueBinding<StringPath, String> () { @Override public Predicate bind(StringPath path, Collection<? extends String> values) { BooleanBuilder predicate = new BooleanBuilder(); values.forEach( value -> predicate.or(path.containsIgnoreCase(value))); return predicate; } });