美文网首页
聊聊PowerJob的QueryConvertUtils

聊聊PowerJob的QueryConvertUtils

作者: go4it | 来源:发表于2024-01-14 09:24 被阅读0次

    本文主要研究一下PowerJob的QueryConvertUtils

    QueryConvertUtils

    tech/powerjob/server/persistence/QueryConvertUtils.java

    public class QueryConvertUtils {
    
        public static <T> Specification<T> toSpecification(PowerQuery powerQuery) {
    
            return (Specification<T>) (root, query, cb) -> {
                List<Predicate> predicates = Lists.newLinkedList();
                Field[] fields = powerQuery.getClass().getDeclaredFields();
                try {
                    for (Field field : fields) {
                        field.setAccessible(true);
                        String fieldName = field.getName();
                        Object fieldValue = field.get(powerQuery);
                        if (fieldValue == null) {
                            continue;
                        }
                        if (fieldName.endsWith(PowerQuery.EQUAL)) {
                            String colName = StringUtils.substringBeforeLast(fieldName, PowerQuery.EQUAL);
                            predicates.add(cb.equal(root.get(colName), fieldValue));
                        } else if (fieldName.endsWith(PowerQuery.NOT_EQUAL)) {
                            String colName = StringUtils.substringBeforeLast(fieldName, PowerQuery.NOT_EQUAL);
                            predicates.add(cb.notEqual(root.get(colName), fieldValue));
                        } else if (fieldName.endsWith(PowerQuery.LIKE)) {
                            String colName = StringUtils.substringBeforeLast(fieldName, PowerQuery.LIKE);
                            predicates.add(cb.like(root.get(colName), convertLikeParams(fieldValue)));
                        } else if (fieldName.endsWith(PowerQuery.NOT_LIKE)) {
                            String colName = StringUtils.substringBeforeLast(fieldName, PowerQuery.NOT_LIKE);
                            predicates.add(cb.notLike(root.get(colName), convertLikeParams(fieldValue)));
                        } else if (fieldName.endsWith(PowerQuery.LESS_THAN)) {
                            String colName = StringUtils.substringBeforeLast(fieldName, PowerQuery.LESS_THAN);
                            predicates.add(cb.lessThan(root.get(colName), (Comparable)fieldValue));
                        } else if (fieldName.endsWith(PowerQuery.GREATER_THAN)) {
                            String colName = StringUtils.substringBeforeLast(fieldName, PowerQuery.GREATER_THAN);
                            predicates.add(cb.greaterThan(root.get(colName), (Comparable)fieldValue));
                        } else if (fieldName.endsWith(PowerQuery.LESS_THAN_EQUAL)) {
                            String colName = StringUtils.substringBeforeLast(fieldName, PowerQuery.LESS_THAN_EQUAL);
                            predicates.add(cb.lessThanOrEqualTo(root.get(colName), (Comparable)fieldValue));
                        } else if (fieldName.endsWith(PowerQuery.GREATER_THAN_EQUAL)) {
                            String colName = StringUtils.substringBeforeLast(fieldName, PowerQuery.GREATER_THAN_EQUAL);
                            predicates.add(cb.greaterThanOrEqualTo(root.get(colName), (Comparable)fieldValue));
                        } else if (fieldName.endsWith(PowerQuery.IN)) {
                            String colName = StringUtils.substringBeforeLast(fieldName, PowerQuery.IN);
                            predicates.add(root.get(colName).in(convertInParams(fieldValue)));
                        } else if (fieldName.endsWith(PowerQuery.NOT_IN)) {
                            String colName = StringUtils.substringBeforeLast(fieldName, PowerQuery.NOT_IN);
                            predicates.add(cb.not(root.get(colName).in(convertInParams(fieldValue))));
                        } else if (fieldName.endsWith(PowerQuery.IS_NULL)) {
                            String colName = StringUtils.substringBeforeLast(fieldName, PowerQuery.IS_NULL);
                            predicates.add(cb.isNull(root.get(colName)));
                        } else if (fieldName.endsWith(PowerQuery.IS_NOT_NULL)) {
                            String colName = StringUtils.substringBeforeLast(fieldName, PowerQuery.IS_NOT_NULL);
                            predicates.add(cb.isNotNull(root.get(colName)));
                        }
                    }
                } catch (Exception e) {
                    log.warn("[QueryConvertUtils] convert failed for query: {}", query, e);
                    throw new PowerJobException("convert query object failed, maybe you should redesign your query object!");
                }
    
                if (powerQuery.getAppIdEq() != null) {
                    predicates.add(cb.equal(root.get("appId"), powerQuery.getAppIdEq()));
                }
    
                return query.where(predicates.toArray(new Predicate[0])).getRestriction();
            };
        }
    
        private static String convertLikeParams(Object o) {
            String s = (String) o;
            if (!s.startsWith("%")) {
                s = "%" + s;
            }
            if (!s.endsWith("%")) {
                s = s + "%";
            }
            return s;
        }
    
        private static Object[] convertInParams(Object o) {
            // FastJSON, 永远滴神!
            return JSONArray.parseArray(JSONArray.toJSONString(o)).toArray();
        }
    }    
    

    QueryConvertUtils提供了toSpecification静态方法,用于将PowerQuery转换为jpa的Specification

    PowerQuery

    public abstract class PowerQuery {
    
        public static String EQUAL = "Eq";
    
        public static String NOT_EQUAL = "NotEq";
    
        public static String LIKE = "Like";
    
        public static String NOT_LIKE = "NotLike";
    
        public static String LESS_THAN = "Lt";
    
        public static String LESS_THAN_EQUAL = "LtEq";
    
        public static String GREATER_THAN = "Gt";
    
        public static String GREATER_THAN_EQUAL = "GtEq";
    
        public static String IN = "In";
    
        public static String NOT_IN = "NotIn";
    
        public static String IS_NULL = "IsNull";
    
        public static String IS_NOT_NULL = "IsNotNull";
    
        private Long appIdEq;
    }
    

    PowerQuery是个抽象类,定义了一系列操作符

    JobInfoQuery

    tech/powerjob/common/request/query/JobInfoQuery.java

    @Getter
    @Setter
    @Accessors(chain = true)
    public class JobInfoQuery extends PowerQuery {
    
        private Long idEq;
        private Long idLt;
        private Long idGt;
    
        private String jobNameEq;
        private String jobNameLike;
    
        private String jobDescriptionLike;
    
        private String jobParamsLike;
    
        private List<Integer> timeExpressionTypeIn;
        private List<Integer> executeTypeIn;
        private List<Integer> processorTypeIn;
    
        private String processorInfoEq;
        private String processorInfoLike;
    
        private List<Integer> statusIn;
        private Long nextTriggerTimeGt;
        private Long nextTriggerTimeLt;
    
        private String notifyUserIdsLike;
    
        private Date gmtCreateLt;
        private Date gmtCreateGt;
    
        private Date gmtModifiedLt;
        private Date gmtModifiedGt;
    
        private Integer dispatchStrategyEq;
    
        private String tagEq;
    }
    

    JobInfoQuery继承了PowerQuery,它根据要查询的字段及操作定义了诸如idEq,idLt,idGt的属性

    InstanceService

    tech/powerjob/server/core/instance/InstanceService.java

        public List<InstanceInfoDTO> queryInstanceInfo(PowerQuery powerQuery) {
            return instanceInfoRepository
                    .findAll(QueryConvertUtils.toSpecification(powerQuery))
                    .stream()
                    .map(InstanceService::directConvert)
                    .collect(Collectors.toList());
        }
    

    InstanceService的queryInstanceInfo方法使用QueryConvertUtils.toSpecification(powerQuery)将powerQuery转换为Specification,再利用JpaSpecificationExecutor的findAll(Specification)进行查询

    小结

    QueryConvertUtils提供了toSpecification静态方法,用于将PowerQuery转换为jpa的Specification,其约定query的属性以字段名+操作符构成,toSpecification根据这个规则来解析并转换为Specification,之后就可以利用jpa进行查询。

    相关文章

      网友评论

          本文标题:聊聊PowerJob的QueryConvertUtils

          本文链接:https://www.haomeiwen.com/subject/ilgqodtx.html