前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊PowerJob的QueryConvertUtils

聊聊PowerJob的QueryConvertUtils

作者头像
code4it
发布2024-01-19 16:50:31
850
发布2024-01-19 16:50:31
举报
文章被收录于专栏:码匠的流水账码匠的流水账

本文主要研究一下PowerJob的QueryConvertUtils

QueryConvertUtils

tech/powerjob/server/persistence/QueryConvertUtils.java

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
@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

代码语言:javascript
复制
    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进行查询。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-01-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码匠的流水账 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • QueryConvertUtils
  • PowerQuery
  • JobInfoQuery
  • InstanceService
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档