
ru.sergkorot.dynamic.util.SpecificationUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spring-boot-operation-starter Show documentation
Show all versions of spring-boot-operation-starter Show documentation
Library for dynamic searching into the databases
The newest version!
package ru.sergkorot.dynamic.util;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Predicate;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.function.TriFunction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.NonNull;
import org.springframework.util.CollectionUtils;
import java.util.Arrays;
import java.util.Collection;
import java.util.function.Function;
/**
* @author Sergey Korotaev
* Util is used for building different specifications for request
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class SpecificationUtils {
/**
* Find column equals specified
*
* @param value - the value to which the entry in the database should be equivalent
* @param columnName - name of column into the database
* @param - the entity for which the request is being built
* @return Specification
*/
@NonNull
public static Specification findByColumnEquals(Object value, @NonNull String columnName) {
return (root, criteriaQuery, criteriaBuilder) ->
criteriaBuilder.equal(root.get(columnName), value);
}
/**
* Find column not equals specified
*
* @param value - the value to which the entry in the database should not be equivalent
* @param columnName - name of column into the database
* @param - the entity for which the request is being built
* @return Specification
*/
@NonNull
public static Specification findByColumnNotEquals(Object value, @NonNull String columnName) {
return (root, criteriaQuery, criteriaBuilder) ->
criteriaBuilder.notEqual(root.get(columnName), value);
}
/**
* Find column like specified
*
* @param value - the value to which the entry in the database should be similar
* @param columnName - name of columns into the database
* @param - the entity for which the request is being built
* @return Specification
*/
@NonNull
public static Specification findByColumnsLike(@NonNull String value, @NonNull Collection columnName) {
if (!value.contains("%")) {
value = "%" + value + "%";
}
String textForSearch = value.toLowerCase();
return (root, criteriaQuery, criteriaBuilder) ->
criteriaBuilder.or(columnName.stream()
.map(element -> criteriaBuilder.like(criteriaBuilder.lower(root.get(element)), textForSearch))
.toArray(Predicate[]::new));
}
/**
* Find column less than specified value
*
* @param value - the value to which the entry in the database should be less
* @param columnName - name of column into the database
* @param - the entity for which the request is being built
* @param - comparable value
* @return Specification
*/
@NonNull
public static > Specification lessThan(Y value, @NonNull String columnName) {
if (value == null) {
return Specification.where(null);
}
return (root, query, criteriaBuilder) -> criteriaBuilder.lessThan(root.get(columnName), value);
}
/**
* Find column greater than specified value
*
* @param value - the value to which the entry in the database should be greater
* @param columnName - name of column into the database
* @param - the entity for which the request is being built
* @param - comparable value
* @return Specification
*/
@NonNull
public static > Specification greaterThan(Y value, @NonNull String columnName) {
if (value == null) {
return Specification.where(null);
}
return (root, query, criteriaBuilder) -> criteriaBuilder.greaterThan(root.get(columnName), value);
}
/**
* Find column less than or equals specified value
*
* @param value - the value to which the entry in the database should be less or equals
* @param columnName - name of column into the database
* @param - the entity for which the request is being built
* @param - comparable value
* @return Specification
*/
@NonNull
public static > Specification lessThanOrEqual(Y value, @NonNull String columnName) {
if (value == null) {
return Specification.where(null);
}
return (root, query, criteriaBuilder) -> criteriaBuilder.lessThanOrEqualTo(root.get(columnName), value);
}
/**
* Find column greater than or equals specified value
*
* @param value - the value to which the entry in the database should be greater or equals
* @param columnName - name of column into the database
* @param - the entity for which the request is being built
* @param - comparable value
* @return Specification
*/
@NonNull
public static > Specification greaterThanOrEqual(Y value, @NonNull String columnName) {
if (value == null) {
return Specification.where(null);
}
return (root, query, criteriaBuilder) -> criteriaBuilder.greaterThanOrEqualTo(root.get(columnName), value);
}
/**
* Find entry where value into the column contains in specified collection
*
* @param collection - collection values for searching
* @param columnName - name of column into the database
* @param - the entity for which the request is being built
* @return Specification
*/
@NonNull
public static Specification findByCollectionIn(@NonNull Collection> collection, @NonNull String columnName) {
Specification specification;
if (CollectionUtils.isEmpty(collection)) {
specification = findNothing();
} else {
specification = (root, criteriaQuery, criteriaBuilder) ->
root.get(columnName).in(collection);
}
return specification;
}
/**
* Find entry where value into the column not contains in specified collection
*
* @param collection - collection values for searching
* @param columnName - name of column into the database
* @param - the entity for which the request is being built
* @return Specification
*/
@NonNull
public static Specification findByCollectionNotIn(@NonNull Collection> collection, @NonNull String columnName) {
Specification specification;
if (CollectionUtils.isEmpty(collection)) {
specification = findNothing();
} else {
specification = (root, criteriaQuery, criteriaBuilder) ->
criteriaBuilder.not(root.get(columnName).in(collection));
}
return specification;
}
/**
* Find entry where specified column is null
*
* @param columnName - name of column into the database
* @param - the entity for which the request is being built
* @return Specification
*/
@NonNull
public static Specification findByColumnIsNull(@NonNull String columnName) {
return (root, query, criteriaBuilder) ->
criteriaBuilder.isNull(root.get(columnName));
}
/**
* Find nothing into the database
*
* @param - the entity for which the request is being built
* @return Specification
*/
@NonNull
public static Specification findNothing() {
return (root, criteriaQuery, criteriaBuilder) ->
criteriaBuilder.conjunction().not();
}
/**
* Find all entry into the database
*
* @param - the entity for which the request is being built
* @return Specification
*/
@NonNull
public static Specification findAll() {
return (root, query, criteriaBuilder) ->
query.where(criteriaBuilder.conjunction()).getRestriction();
}
/**
* Find entry which value contains all specified elements
*
* @param value - single or list elements with comma separator
* @param columnName - name of column into the database
* @param - the entity for which the request is being built
* @return Specification
*/
@NonNull
public static Specification contains(@NonNull Object value, @NonNull String columnName) {
return (root, query, criteriaBuilder) -> query.where(criteriaBuilder.and(
Arrays.stream(value.toString().split(","))
.map(v ->
createPredicate.apply(
trimAndGlue.apply(v),
root.get(columnName),
criteriaBuilder)
)
.toArray(Predicate[]::new)
)).getRestriction();
}
private static final Function trimAndGlue = v -> "%" + v.trim() + "%";
private static final TriFunction, CriteriaBuilder, Predicate> createPredicate =
(v, expression, cb) -> cb.like(expression.as(String.class), v);
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy