All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.feingto.cloud.data.jpa.specification.bean.Condition Maven / Gradle / Ivy

package com.feingto.cloud.data.jpa.specification.bean;

import com.feingto.cloud.kit.reflection.BeanConvertKit;
import lombok.Data;
import lombok.experimental.Accessors;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.util.WebUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.feingto.cloud.data.jpa.specification.bean.RuleGroup.UnionOperator.AND;
import static com.feingto.cloud.data.jpa.specification.bean.RuleGroup.UnionOperator.OR;

/**
 * 查询参数过滤规则
 * 

* JSON格式: * {"conditions":[{"groups":[{"rules":[{"property":"id.sn","op":"EQ","value":"001"},{"property":"enabled","op":"EQ","value":"ENABLED"}],"op":"and"}],"rules":[{"property":"type","op":"EQ","value":1}],"op":"or"}],"rules":[{"property":"status","op":"EQ","value":1}],"op":"and"} * * @author longfei */ @Data @Accessors(chain = true) public class Condition implements Serializable { private static final long serialVersionUID = 4950188917289587920L; /** * 查询参数前缀 */ private static final String SEARCH_PREFIX = "search_"; /** * 查询参数分隔符 */ private static final String SEARCH_DELIMITER = "_"; /** * 全部运算符 */ private static final List OPERATORS = Stream.of(Rule.Operator.values()) .map(Enum::name) .collect(Collectors.toList()); private List conditions = new ArrayList<>(); private List groups = new ArrayList<>(); private List rules = new ArrayList<>(); /** * 操作符(AND 或者 OR) */ private RuleGroup.UnionOperator op; /** * group by * 此属性不支持 Oracle, Oracle select 出来的字段必须在 group by 后边出现. *

* Oracle group by @Query 使用说明: * 返回单属性集合 List: @Query("select e.setProperty from Entity e group by e.setProperty") * 返回多属性集合 List: @Query("select new Entity(e.property1, e.property2) from Entity e group by e.property1, e.property2"), 必须要有public Entity(String property1, String property2)构造函数. */ private List groupByNames = new ArrayList<>(); /** * 是否去重 */ private boolean distinct; /** * 备注 */ private String remark; public static Condition build() { return new Condition(); } /** * request参数转换为查询规则 * 参数名示例: * search_EQ_status * search_LIKE_username_OR_realName * search_NEQ_groups.id_OR_ISNULL_groups.id */ public static Condition build(HttpServletRequest request) { Condition condition = Condition.build(); Optional.ofNullable(request) .ifPresent(req -> WebUtils.getParametersStartingWith(req, SEARCH_PREFIX).entrySet().stream() .filter(entry -> !ObjectUtils.isEmpty(entry.getValue())) .forEach(entry -> parseParameter(condition, entry.getKey(), (String) entry.getValue()))); return condition; } /** * 解析参数, 提取 AND/OR 并转换为查询规则 * * @param condition Condition * @param paramName 参数名 * @param paramValue 参数值 */ private static void parseParameter(Condition condition, String paramName, String paramValue) { String[] names = StringUtils.splitByWholeSeparator(paramName, SEARCH_DELIMITER); if (names.length == 0) { return; } List operators = new ArrayList<>(); RuleGroup.UnionOperator unionOperator = null; int i = 0; for (String name : names) { if (OPERATORS.contains(name)) { operators.add(Rule.Operator.valueOf(name)); } else if (OR.name().equals(name) || AND.name().equals(name)) { unionOperator = RuleGroup.UnionOperator.valueOf(name); } else if (CollectionUtils.isNotEmpty(operators)) { condition.getRules().add(new Rule() .setProperty(name) .setOp(i < operators.size() ? operators.get(i) : operators.get(operators.size() - 1)) .setValue(paramValue.contains(",") ? Arrays.asList(paramValue.split(",")) : paramValue.trim())); i++; } } if (OR.equals(unionOperator)) { condition.or(); } else { condition.and(); } } public Condition eq(String property, Object value) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.EQ).setValue(value)); return this; } public Condition ne(String property, Object value) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.NEQ).setValue(value)); return this; } public Condition slike(String property, Object value) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.SLIKE).setValue(value)); return this; } public Condition elike(String property, Object value) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.ELIKE).setValue(value)); return this; } public Condition like(String property, Object value) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.LIKE).setValue(value)); return this; } public Condition gt(String property, Object value) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.GT).setValue(value)); return this; } public Condition lt(String property, Object value) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.LT).setValue(value)); return this; } public Condition gte(String property, Object value) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.GTE).setValue(value)); return this; } public Condition lte(String property, Object value) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.LTE).setValue(value)); return this; } public Condition between(String property, Object lo, Object hi) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.GT).setValue(lo)); this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.LT).setValue(hi)); return this; } public Condition in(String property, Collection values) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.IN).setValue(values)); return this; } public Condition notIn(String property, Collection values) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.NIN).setValue(values)); return this; } public Condition isEmpty(String property) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.ISEMPTY)); return this; } public Condition isNotEmpty(String property) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.ISNOTEMPTY)); return this; } public Condition isNull(String property) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.ISNULL)); return this; } public Condition isNotNull(String property) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.ISNOTNULL)); return this; } public Condition isBoolean(String property, Object value) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.ISBOOLEAN).setValue(value)); return this; } public Condition isTrue(String property) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.ISTRUE)); return this; } public Condition isFalse(String property) { this.rules.add(new Rule().setProperty(property).setOp(Rule.Operator.ISFALSE)); return this; } public Condition and() { return this.setRule(AND); } public Condition or() { return this.setRule(OR); } public Condition AND() { return this.setRuleGroup(AND); } public Condition OR() { return this.setRuleGroup(OR); } public Condition setRule(RuleGroup.UnionOperator op) { if (CollectionUtils.isNotEmpty(this.rules)) { this.groups.add(new RuleGroup() .setRules(BeanConvertKit.convert(this.rules, Rule.class)) .setOp(op)); this.rules.clear(); } return this; } public Condition setRuleGroup(RuleGroup.UnionOperator op) { if (CollectionUtils.isNotEmpty(this.groups)) { this.conditions.add(new Condition() .setGroups(BeanConvertKit.convert(this.groups, RuleGroup.class)) .setRules(BeanConvertKit.convert(this.rules, Rule.class)) .setOp(op)); this.groups.clear(); this.rules.clear(); } else { this.op(op); } return this; } public Condition op(RuleGroup.UnionOperator operator) { this.op = operator; return this; } public Condition distinct() { this.distinct = true; return this; } public Condition groupBy(String property) { this.groupByNames.add(property); return this; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy