From 64c36d402a4bb7a77e1fc985b7a1193df67e6371 Mon Sep 17 00:00:00 2001 From: tjq Date: Sat, 16 Jan 2021 00:44:49 +0800 Subject: [PATCH] feat: develop QueryConvertUtils to redefine the query --- .../kfcfans/powerjob/client/OhMyClient.java | 14 ++- .../kfcfans/powerjob/common/PowerQuery.java | 44 ++++++++++ .../common/request/http/JobQuery.java | 36 -------- .../common/utils/QueryConvertUtils.java | 88 +++++++++++++++++++ .../core/repository/JobInfoRepository.java | 3 +- .../powerjob/server/service/JobService.java | 8 ++ .../web/controller/OpenAPIController.java | 6 +- 7 files changed, 150 insertions(+), 49 deletions(-) create mode 100644 powerjob-common/src/main/java/com/github/kfcfans/powerjob/common/PowerQuery.java delete mode 100644 powerjob-common/src/main/java/com/github/kfcfans/powerjob/common/request/http/JobQuery.java create mode 100644 powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/common/utils/QueryConvertUtils.java diff --git a/powerjob-client/src/main/java/com/github/kfcfans/powerjob/client/OhMyClient.java b/powerjob-client/src/main/java/com/github/kfcfans/powerjob/client/OhMyClient.java index ff708661..3da848ed 100644 --- a/powerjob-client/src/main/java/com/github/kfcfans/powerjob/client/OhMyClient.java +++ b/powerjob-client/src/main/java/com/github/kfcfans/powerjob/client/OhMyClient.java @@ -1,11 +1,7 @@ package com.github.kfcfans.powerjob.client; import com.alibaba.fastjson.JSONObject; -import com.github.kfcfans.powerjob.common.InstanceStatus; -import com.github.kfcfans.powerjob.common.OmsConstant; -import com.github.kfcfans.powerjob.common.OpenAPIConstant; -import com.github.kfcfans.powerjob.common.PowerJobException; -import com.github.kfcfans.powerjob.common.request.http.JobQuery; +import com.github.kfcfans.powerjob.common.*; import com.github.kfcfans.powerjob.common.request.http.SaveJobInfoRequest; import com.github.kfcfans.powerjob.common.request.http.SaveWorkflowRequest; import com.github.kfcfans.powerjob.common.response.*; @@ -146,13 +142,13 @@ public class OhMyClient { /** * Query JobInfo by query - * @param jobQuery JobQuery + * @param powerQuery JobQuery * @return JobInfo */ - public ResultDTO> queryJob(JobQuery jobQuery) { - jobQuery.appIdEq(appId); + public ResultDTO> queryJob(PowerQuery powerQuery) { + powerQuery.setAppIdEq(appId); MediaType jsonType = MediaType.parse("application/json; charset=utf-8"); - String json = JSONObject.toJSONString(jobQuery); + String json = JsonUtils.toJSONStringUnsafe(powerQuery); String post = postHA(OpenAPIConstant.Query_JOB, RequestBody.create(jsonType, json)); return JSONObject.parseObject(post, LIST_JOB_RESULT_TYPE); } diff --git a/powerjob-common/src/main/java/com/github/kfcfans/powerjob/common/PowerQuery.java b/powerjob-common/src/main/java/com/github/kfcfans/powerjob/common/PowerQuery.java new file mode 100644 index 00000000..09203229 --- /dev/null +++ b/powerjob-common/src/main/java/com/github/kfcfans/powerjob/common/PowerQuery.java @@ -0,0 +1,44 @@ +package com.github.kfcfans.powerjob.common; + +/** + * PowerJob Query interface + * + * @author tjq + * @since 2021/1/15 + */ +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; + + public Long getAppIdEq() { + return appIdEq; + } + + public void setAppIdEq(Long appIdEq) { + this.appIdEq = appIdEq; + } +} diff --git a/powerjob-common/src/main/java/com/github/kfcfans/powerjob/common/request/http/JobQuery.java b/powerjob-common/src/main/java/com/github/kfcfans/powerjob/common/request/http/JobQuery.java deleted file mode 100644 index 07c35c5a..00000000 --- a/powerjob-common/src/main/java/com/github/kfcfans/powerjob/common/request/http/JobQuery.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.github.kfcfans.powerjob.common.request.http; - -import lombok.Data; -import lombok.experimental.Accessors; - -import java.util.List; - -/** - * JobQuery - * eq: equals, = - * gt: greater than, > - * lt: less than, < - * - * @author tjq - * @since 2021/1/15 - */ -@Data -@Accessors(fluent = true, chain = true) -public class JobQuery { - - private Long appIdEq; - - private Long idEq; - private Long idLt; - private Long idGt; - - private List statusIn; - private List statusNotIn; - - private Long nextTriggerTimeLt; - private Long nextTriggerTimeGt; - - private String nameLike; - - private Long limit; -} diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/common/utils/QueryConvertUtils.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/common/utils/QueryConvertUtils.java new file mode 100644 index 00000000..1683a87c --- /dev/null +++ b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/common/utils/QueryConvertUtils.java @@ -0,0 +1,88 @@ +package com.github.kfcfans.powerjob.server.common.utils; + +import com.alibaba.fastjson.JSON; +import com.github.kfcfans.powerjob.common.PowerJobException; +import com.github.kfcfans.powerjob.common.PowerQuery; +import com.google.common.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.data.jpa.domain.Specification; + +import javax.persistence.criteria.*; +import java.lang.reflect.Field; +import java.util.List; + +/** + * auto convert query to Specification + * + * @author tjq + * @since 2021/1/15 + */ +@Slf4j +@SuppressWarnings("unchecked, rawtypes") +public class QueryConvertUtils { + + public static Specification autoConvert(PowerQuery powerQuery) { + + return (Specification) (root, query, cb) -> { + List predicates = Lists.newLinkedList(); + Field[ ] fields = query.getClass().getDeclaredFields(); + try { + for (Field field : fields) { + 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), (String) fieldValue)); + } else if (fieldName.endsWith(PowerQuery.NOT_LIKE)) { + String colName = StringUtils.substringBeforeLast(fieldName, PowerQuery.NOT_LIKE); + predicates.add(cb.notLike(root.get(colName), (String) 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(fieldValue)); + } else if (fieldName.endsWith(PowerQuery.NOT_IN)) { + String colName = StringUtils.substringBeforeLast(fieldName, PowerQuery.NOT_IN); + predicates.add(cb.not(root.get(colName).in(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: {}", JSON.toJSON(query)); + throw new PowerJobException("convert query object failed, maybe you should redesign your query object!"); + } + + return query.where(predicates.toArray(new Predicate[0])).getRestriction(); + }; + } + + public static void main(String[] args) { + String s = "appIdEq"; + System.out.println(StringUtils.substringBeforeLast(s, "Eq")); + } +} diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/persistence/core/repository/JobInfoRepository.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/persistence/core/repository/JobInfoRepository.java index 2f93b6d1..146b3711 100644 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/persistence/core/repository/JobInfoRepository.java +++ b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/persistence/core/repository/JobInfoRepository.java @@ -4,6 +4,7 @@ import com.github.kfcfans.powerjob.server.persistence.core.model.JobInfoDO; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import java.util.List; @@ -14,7 +15,7 @@ import java.util.List; * @author tjq * @since 2020/4/1 */ -public interface JobInfoRepository extends JpaRepository { +public interface JobInfoRepository extends JpaRepository, JpaSpecificationExecutor { // 调度专用 diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/JobService.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/JobService.java index f600b2f3..0a3104cb 100644 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/JobService.java +++ b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/JobService.java @@ -2,6 +2,7 @@ package com.github.kfcfans.powerjob.server.service; import com.github.kfcfans.powerjob.common.InstanceStatus; import com.github.kfcfans.powerjob.common.PowerJobException; +import com.github.kfcfans.powerjob.common.PowerQuery; import com.github.kfcfans.powerjob.common.TimeExpressionType; import com.github.kfcfans.powerjob.common.request.http.SaveJobInfoRequest; import com.github.kfcfans.powerjob.common.response.JobInfoDTO; @@ -9,6 +10,7 @@ import com.github.kfcfans.powerjob.server.common.SJ; import com.github.kfcfans.powerjob.server.common.constans.SwitchableStatus; import com.github.kfcfans.powerjob.server.common.redirect.DesignateServer; import com.github.kfcfans.powerjob.server.common.utils.CronExpression; +import com.github.kfcfans.powerjob.server.common.utils.QueryConvertUtils; import com.github.kfcfans.powerjob.server.persistence.core.model.InstanceInfoDO; import com.github.kfcfans.powerjob.server.persistence.core.model.JobInfoDO; import com.github.kfcfans.powerjob.server.persistence.core.repository.InstanceInfoRepository; @@ -17,6 +19,7 @@ import com.github.kfcfans.powerjob.server.service.instance.InstanceService; import com.github.kfcfans.powerjob.server.service.instance.InstanceTimeWheelService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; +import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; @@ -97,6 +100,11 @@ public class JobService { return jobInfoRepository.findByAppId(appId).stream().map(JobService::convert).collect(Collectors.toList()); } + public List queryJob(PowerQuery powerQuery) { + Specification specification = QueryConvertUtils.autoConvert(powerQuery); + return jobInfoRepository.findAll(specification).stream().map(JobService::convert).collect(Collectors.toList()); + } + /** * 手动立即运行某个任务 * @param jobId 任务ID diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/web/controller/OpenAPIController.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/web/controller/OpenAPIController.java index ad457598..e39bc075 100644 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/web/controller/OpenAPIController.java +++ b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/web/controller/OpenAPIController.java @@ -2,7 +2,7 @@ package com.github.kfcfans.powerjob.server.web.controller; import com.github.kfcfans.powerjob.common.InstanceStatus; import com.github.kfcfans.powerjob.common.OpenAPIConstant; -import com.github.kfcfans.powerjob.common.request.http.JobQuery; +import com.github.kfcfans.powerjob.common.PowerQuery; import com.github.kfcfans.powerjob.common.request.http.SaveWorkflowRequest; import com.github.kfcfans.powerjob.server.service.AppInfoService; import com.github.kfcfans.powerjob.server.service.CacheService; @@ -68,8 +68,8 @@ public class OpenAPIController { } @PostMapping(OpenAPIConstant.Query_JOB) - public ResultDTO> queryJob(@RequestBody JobQuery jobQuery) { - return ResultDTO.failed("developing"); + public ResultDTO> queryJob(@RequestBody PowerQuery powerQuery) { + return ResultDTO.success(jobService.queryJob(powerQuery)); } @PostMapping(OpenAPIConstant.DELETE_JOB)