mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-02-08 11:59:13 +00:00
63 lines
2.6 KiB
Java
63 lines
2.6 KiB
Java
package com.imprimelibros.erp.datatables;
|
|
|
|
import org.springframework.data.jpa.domain.Specification;
|
|
import jakarta.persistence.criteria.*;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
public class DataTablesSpecification {
|
|
|
|
/**
|
|
* Crea una Specification con búsqueda global y por columna (LIKE
|
|
* case-insensitive)
|
|
*
|
|
* @param dt request de datatables
|
|
* @param searchableFields campos del entity para el buscador global
|
|
*/
|
|
public static <T> Specification<T> build(DataTablesRequest dt, List<String> searchableFields) {
|
|
return (root, query, cb) -> {
|
|
List<Predicate> ands = new ArrayList<>();
|
|
|
|
// Filtro por columna (si lo usas en el cliente)
|
|
for (int i = 0; i < dt.columns.size(); i++) {
|
|
DataTablesRequest.Column col = dt.columns.get(i);
|
|
if (col.searchable && col.search != null && col.search.value != null && !col.search.value.isEmpty()) {
|
|
try {
|
|
Path<?> path = root;
|
|
String[] parts = col.name.split("\\.");
|
|
for (String part : parts) {
|
|
path = path.get(part);
|
|
}
|
|
ands.add(like(cb, path, col.search.value));
|
|
} catch (IllegalArgumentException ex) {
|
|
// columna no mapeada o relación: la ignoramos
|
|
//System.out.println("[DT] columna no mapeada o relación: " + col.name);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Búsqueda global
|
|
if (dt.search != null && dt.search.value != null && !dt.search.value.isEmpty()
|
|
&& !searchableFields.isEmpty()) {
|
|
String term = "%" + dt.search.value.trim().toLowerCase() + "%";
|
|
List<Predicate> ors = new ArrayList<>();
|
|
for (String f : searchableFields) {
|
|
try {
|
|
ors.add(cb.like(cb.lower(root.get(f).as(String.class)), term));
|
|
} catch (IllegalArgumentException ex) {
|
|
// campo no simple: lo saltamos
|
|
}
|
|
}
|
|
if (!ors.isEmpty())
|
|
ands.add(cb.or(ors.toArray(new Predicate[0])));
|
|
}
|
|
|
|
return ands.isEmpty() ? cb.conjunction() : cb.and(ands.toArray(new Predicate[0]));
|
|
};
|
|
}
|
|
|
|
private static Predicate like(CriteriaBuilder cb, Path<?> path, String value) {
|
|
return cb.like(cb.lower(path.as(String.class)), "%" + value.trim().toLowerCase() + "%");
|
|
}
|
|
}
|