org.onetwo.jpa.hibernate.SpecificationQuerys Maven / Gradle / Ivy
The newest version!
package org.onetwo.jpa.hibernate;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.From;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.SingularAttribute;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.util.Assert;
/**
* 在spring data的 Specifications 上扩展
* 没有全部实现操作符,用到哪个实现那个。。。
* @author weishao zeng
*
*/
@SuppressWarnings("serial")
public class SpecificationQuerys implements Specification, Serializable {
public static final Order sortAsc(SingularAttribute, ?> field){
return new Order(Direction.ASC, field.getName());
}
public static final Order sortAsc(String field){
return new Order(Direction.ASC, field);
}
public static final Order sortDesc(String field){
return new Order(Direction.DESC, field);
}
public static final Order sortDesc(SingularAttribute, ?> field){
return new Order(Direction.DESC, field.getName());
}
private final Specification spec;
private Sort sort;
private SpecificationQuerys(Specification spec) {
this.spec = spec;
this.sort = Sort.by(new Order[0]);
}
private SpecificationQuerys(Specification spec, Sort sort) {
super();
this.spec = spec;
this.sort = sort;
}
public static SpecificationQuerys where(Specification spec) {
return new SpecificationQuerys(spec);
}
public static SpecificationQuerys from(Class clazz) {
return new SpecificationQuerys(null);
}
public QueryCauseField field(String field) {
return new QueryCauseField(field);
}
public QueryCauseField field(SingularAttribute, ?> field) {
return new QueryCauseField(field.getName());
}
public SpecificationQuerys asc(String... fields) {
Order[] orders = Stream.of(fields)
.map(f->sortAsc(f))
.collect(Collectors.toList())
.toArray(new Order[0]);
return orderBy(orders);
}
public SpecificationQuerys asc(SingularAttribute, ?>... fields) {
Order[] orders = Stream.of(fields)
.map(f->sortAsc(f))
.collect(Collectors.toList())
.toArray(new Order[0]);
return orderBy(orders);
}
public SpecificationQuerys desc(String... fields) {
Order[] orders = Stream.of(fields)
.map(f->sortDesc(f))
.collect(Collectors.toList())
.toArray(new Order[0]);
return orderBy(orders);
}
public SpecificationQuerys desc(SingularAttribute, ?>... fields) {
Order[] orders = Stream.of(fields)
.map(f->sortDesc(f))
.collect(Collectors.toList())
.toArray(new Order[0]);
return orderBy(orders);
}
public SpecificationQuerys orderBy(Order... orders) {
this.sort = Sort.by(orders);
return this;
}
public SpecificationQuerys sort(Sort sort) {
this.sort = sort;
return this;
}
public SpecificationQuerys and(Specification other) {
return new SpecificationQuerys(new ComposedSpecification(spec, other, CompositionType.AND), this.sort);
}
public SpecificationQuerys or(Specification other) {
return new SpecificationQuerys(new ComposedSpecification(spec, other, CompositionType.OR), this.sort);
}
public static SpecificationQuerys not(Specification spec) {
return new SpecificationQuerys(new NegatedSpecification(spec));
}
public Predicate toPredicate(Root root, CriteriaQuery> query, CriteriaBuilder builder) {
return spec == null ? null : spec.toPredicate(root, query, builder);
}
/***
*
* @author weishao zeng
* @param executor
* @return
*/
public List getList(JpaSpecificationExecutor executor){
List list = executor.findAll(spec, sort);
return list;
}
public Optional getOne(JpaSpecificationExecutor executor){
Optional data = executor.findOne(spec);
return data;
}
/****
* get list and group by
* @author weishao zeng
* @param executor
* @param keyer 决定分组的key,即返回的Map对象的key
* @return
*/
public Map> getMap(JpaSpecificationExecutor executor, Function super T, ? extends K> keyer){
List list = executor.findAll(spec, sort);
return list.stream()
.collect(Collectors.groupingBy(keyer));
}
/**
* Enum for the composition types for {@link Predicate}s.
*
* @author Thomas Darimont
*/
enum CompositionType {
AND {
@Override
public Predicate combine(CriteriaBuilder builder, Predicate lhs, Predicate rhs) {
return builder.and(lhs, rhs);
}
},
OR {
@Override
public Predicate combine(CriteriaBuilder builder, Predicate lhs, Predicate rhs) {
return builder.or(lhs, rhs);
}
};
abstract Predicate combine(CriteriaBuilder builder, Predicate lhs, Predicate rhs);
}
/**
* A {@link Specification} that negates a given {@code Specification}.
*
* @author Thomas Darimont
* @since 1.6
*/
private static class NegatedSpecification implements Specification, Serializable {
private static final long serialVersionUID = 1L;
private final Specification spec;
/**
* Creates a new {@link NegatedSpecification} from the given {@link Specification}
*
* @param spec may be {@iteral null}
*/
public NegatedSpecification(Specification spec) {
this.spec = spec;
}
public Predicate toPredicate(Root root, CriteriaQuery> query, CriteriaBuilder builder) {
return spec == null ? null : builder.not(spec.toPredicate(root, query, builder));
}
}
/**
* A {@link Specification} that combines two given {@code Specification}s via a given {@link CompositionType}.
*
* @author Thomas Darimont
* @since 1.6
*/
private static class ComposedSpecification implements Specification, Serializable {
private static final long serialVersionUID = 1L;
private final Specification lhs;
private final Specification rhs;
private final CompositionType compositionType;
/**
* Creates a new {@link ComposedSpecification} from the given {@link Specification} for the left-hand-side and the
* right-hand-side with the given {@link CompositionType}.
*
* @param lhs may be {@literal null}
* @param rhs may be {@literal null}
* @param compositionType must not be {@literal null}
*/
private ComposedSpecification(Specification lhs, Specification rhs, CompositionType compositionType) {
Assert.notNull(compositionType, "CompositionType must not be null!");
this.lhs = lhs;
this.rhs = rhs;
this.compositionType = compositionType;
}
/**
* Returns {@link Predicate} for the given {@link Root} and {@link CriteriaQuery} that is constructed via the given
* {@link CriteriaBuilder}.
*/
public Predicate toPredicate(Root root, CriteriaQuery> query, CriteriaBuilder builder) {
Predicate otherPredicate = rhs == null ? null : rhs.toPredicate(root, query, builder);
Predicate thisPredicate = lhs == null ? null : lhs.toPredicate(root, query, builder);
return thisPredicate == null ? otherPredicate : otherPredicate == null ? thisPredicate : this.compositionType
.combine(builder, thisPredicate, otherPredicate);
}
}
/***
* 非string类型,不能为null;
* string类型,除了不能为null,还不能为blank
*/
public static final java.util.function.Predicate
© 2015 - 2025 Weber Informatics LLC | Privacy Policy