From 099441a0715a65e6a0eb83f84e8769d67b67daaf Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Fri, 14 Apr 2023 16:12:32 +0800 Subject: [PATCH 01/22] feature: flexible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加动态查询模块,应用于特殊场景。 0.30.0预览版。 --- changelog.md | 4 + .../JointBlockWebAutoConfiguration.java | 8 ++ jointblock-spring-boot-parent/pom.xml | 2 +- .../executor/ArticlePagingQryExeTest.java | 21 ++++ .../flexible/OperationConstant.java | 60 ++++++++++ .../QueryHandlerMethodArgumentResolver.java | 56 +++++++++ .../jointblock/flexible/QueryParam.java | 26 +++++ .../flexible/QueryWrapperBuilder.java | 107 ++++++++++++++++++ .../jointblock/flexible/SearchCriteria.java | 25 ++++ .../jointblock/flexible/package-info.java | 4 + pom.xml | 2 +- 11 files changed, 313 insertions(+), 2 deletions(-) create mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/OperationConstant.java create mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java create mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryParam.java create mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryWrapperBuilder.java create mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/SearchCriteria.java create mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/package-info.java diff --git a/changelog.md b/changelog.md index ade0bd5..6f35867 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,7 @@ +# 0.30.0 +feature: +- flexible模块增加,特殊情况下动态查询`totalChapter[NotIn]=(6|7|8)` + # 0.29.0 feature: - batch mapper功能支持,支持批量插入,批量replace。 diff --git a/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockWebAutoConfiguration.java b/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockWebAutoConfiguration.java index 9194a76..f446034 100644 --- a/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockWebAutoConfiguration.java +++ b/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockWebAutoConfiguration.java @@ -1,6 +1,7 @@ package fun.easycode.joinblock.autoconfigure; import fun.easycode.jointblock.core.*; +import fun.easycode.jointblock.flexible.QueryHandlerMethodArgumentResolver; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; @@ -10,9 +11,11 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.time.LocalDateTime; +import java.util.List; /** * web应用才生效 @@ -23,6 +26,11 @@ import java.time.LocalDateTime; @Slf4j public class JointBlockWebAutoConfiguration implements WebMvcConfigurer, Jackson2ObjectMapperBuilderCustomizer{ + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(new QueryHandlerMethodArgumentResolver()); + } + /** * mvc枚举转换器 * @return EnumeratorConvertFactory diff --git a/jointblock-spring-boot-parent/pom.xml b/jointblock-spring-boot-parent/pom.xml index 7c6ee2b..f710524 100644 --- a/jointblock-spring-boot-parent/pom.xml +++ b/jointblock-spring-boot-parent/pom.xml @@ -27,7 +27,7 @@ 10.10.1 2.1.5.RELEASE 20.0 - 0.29.0 + 0.30.0 2.14.2 diff --git a/jointblock-spring-boot-test/src/test/java/fun/easycode/jointblock/service/executor/ArticlePagingQryExeTest.java b/jointblock-spring-boot-test/src/test/java/fun/easycode/jointblock/service/executor/ArticlePagingQryExeTest.java index f0f71b0..eddbafb 100644 --- a/jointblock-spring-boot-test/src/test/java/fun/easycode/jointblock/service/executor/ArticlePagingQryExeTest.java +++ b/jointblock-spring-boot-test/src/test/java/fun/easycode/jointblock/service/executor/ArticlePagingQryExeTest.java @@ -9,6 +9,9 @@ import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + @RunWith(SpringRunner.class) @SpringBootTest public class ArticlePagingQryExeTest { @@ -19,4 +22,22 @@ public class ArticlePagingQryExeTest { PageDto pageDto = ExecutorContext.get(ArticlePagingQryExe.class).execute(qry); System.out.println(pageDto.getTotalSize()); } + + public static void main(String[] args) { + Pattern pattern = Pattern.compile("(\\w+?)(\\[.*\\]=)([a-zA-Z0-9\\\\u4e00-\\\\u9fa5()|]+?),"); + Matcher matcher = pattern.matcher("totalChapter[NotIn]=(6|7|8),"); + + Pattern operatorPattern = Pattern.compile("(?<=\\[).*(?=\\])"); + + while (matcher.find()) { + System.out.print(matcher.group(1) + " "); + System.out.print(matcher.group(2)+ " "); + + Matcher operatorMatcher = operatorPattern.matcher(matcher.group(2)); + + System.err.print(operatorMatcher.find() ? operatorMatcher.group() : ""); + System.out.println(matcher.group(3) + " "); + } + + } } diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/OperationConstant.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/OperationConstant.java new file mode 100644 index 0000000..caa5ba5 --- /dev/null +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/OperationConstant.java @@ -0,0 +1,60 @@ +package fun.easycode.jointblock.flexible; + +/** + * 操作符常量 + * @author xuzhen97 + */ +public final class OperationConstant { + /** + * 等于 + */ + public static final String EQ = "Eq"; + /** + * 模糊查询 + */ + public static final String LIKE = "Like"; + /** + * 模糊查询左 + */ + public static final String LIKE_LEFT = "LikeLeft"; + /** + * 模糊查询右 + */ + public static final String LIKE_RIGHT = "LikeRight"; + /** + * 大于 + */ + public static final String GT = "Gt"; + /** + * 小于 + */ + public static final String LT = "Lt"; + /** + * 大于等于 + */ + public static final String GE = "Ge"; + /** + * 小于等于 + */ + public static final String LE = "Le"; + + /** + * in 集合查询 + */ + public static final String IN = "In"; + + /** + * not in 集合查询 + */ + public static final String NOT_IN = "NotIn"; + + /** + * is null 查询 + */ + public static final String IS_NULL = "IsNull"; + + /** + * 排序 + */ + public static final String SORT = "Sort"; +} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java new file mode 100644 index 0000000..5e0523e --- /dev/null +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java @@ -0,0 +1,56 @@ +package fun.easycode.jointblock.flexible; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import fun.easycode.jointblock.exception.CheckException; +import org.springframework.core.MethodParameter; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class QueryHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver { + @Override + public boolean supportsParameter(MethodParameter methodParameter) { + return methodParameter.hasParameterAnnotation(QueryParam.class); + } + + @Override + public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception { + QueryParam queryParam = methodParameter.getParameterAnnotation(QueryParam.class); + + String name = "".equalsIgnoreCase(queryParam.name()) ? queryParam.value() : queryParam.name(); + + if ("".equalsIgnoreCase(name)) { + name = methodParameter.getParameter().getName(); + } + + String value = nativeWebRequest.getParameter(name); + + if (value == null) { + return null; + } + + + return buildQueryWrapper(value, queryParam.root()); + } + + public static QueryWrapper buildQueryWrapper(String value, Class root) { + QueryWrapperBuilder builder = new QueryWrapperBuilder(); + // 整体表达式正则 + Pattern pattern = Pattern.compile("(\\w+?)(\\[.*\\]=)([a-zA-Z0-9\\\\u4e00-\\\\u9fa5]+?),"); + Matcher matcher = pattern.matcher(value + ","); + // 操作符匹配正则 + Pattern operatorPattern = Pattern.compile("(?<=\\[).*(?=\\])"); + while (matcher.find()) { + Matcher operatorMatcher = operatorPattern.matcher(matcher.group(2)); + if(!matcher.find()){ + throw new CheckException("查询条件格式错误"); + } + builder.with(matcher.group(1), operatorMatcher.group(), matcher.group(3)); + } + return builder.build(root); + } +} \ No newline at end of file diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryParam.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryParam.java new file mode 100644 index 0000000..152c769 --- /dev/null +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryParam.java @@ -0,0 +1,26 @@ +package fun.easycode.jointblock.flexible; + +import org.springframework.core.annotation.AliasFor; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface QueryParam { + /** + * Alias for {@link #name}. + */ + @AliasFor("name") String value() default ""; + /** + * The name of the request parameter to bind to. + * + * @since 4.2 + */ + @AliasFor("value") String name() default ""; + Class root(); +} \ No newline at end of file diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryWrapperBuilder.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryWrapperBuilder.java new file mode 100644 index 0000000..0d0c8cf --- /dev/null +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryWrapperBuilder.java @@ -0,0 +1,107 @@ +package fun.easycode.jointblock.flexible; + +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.LambdaUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache; +import fun.easycode.jointblock.exception.CheckException; + +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class QueryWrapperBuilder { + + private List params; + + public QueryWrapperBuilder(){ + params = new ArrayList<>(); + } + + public QueryWrapperBuilder with(String key, String operation, Object value){ + params.add(new SearchCriteria(key, operation, value)); + return this; + } + + public QueryWrapper build(Class tClass){ + if(params.size() == 0){ + return null; + } + + Map columnMap = LambdaUtils.getColumnMap(tClass); + + QueryWrapper queryWrapper = Wrappers.query(); + + for(SearchCriteria criteria : params){ + + String columnKey = LambdaUtils.formatKey(criteria.getKey()); + String tableField = columnMap.get(columnKey).getColumnSelect(); + // 解析查询条件 + analysis(tableField, criteria.getOperation(), criteria.getValue(), queryWrapper); + } + return queryWrapper; + } + + /** + * 解析查询条件 + * @param tableField 字段名 + * @param operation 操作符 + * @param value 值 + * @param wrapper 条件构造器 + * @param 实体类 + */ + private static void analysis(String tableField, String operation, Object value, QueryWrapper wrapper) { + + // 如果是空值,不处理 + if (!ObjectUtil.isNotEmpty(value)) { + return; + } + + if (Objects.equals(OperationConstant.EQ, operation)) { + wrapper.eq(tableField, value); + } else if (Objects.equals(OperationConstant.LIKE, operation)) { + wrapper.like(tableField, value); + } else if (Objects.equals(OperationConstant.LIKE_LEFT, operation)) { + wrapper.likeLeft(tableField, value); + } else if (Objects.equals(OperationConstant.LIKE_RIGHT, operation)) { + wrapper.likeRight(tableField, value); + } else if (Objects.equals(OperationConstant.GT, operation)) { + wrapper.gt(tableField, value); + } else if (Objects.equals(OperationConstant.LT, operation)) { + wrapper.lt(tableField, value); + } else if (Objects.equals(OperationConstant.GE, operation)) { + wrapper.ge(tableField, value); + } else if (Objects.equals(OperationConstant.LE, operation)) { + wrapper.le(tableField, value); + } else if (Objects.equals(OperationConstant.IS_NULL, operation)) { + if ((Boolean) value) { + wrapper.isNull(tableField); + } else { + wrapper.isNotNull(tableField); + } + } else if (Objects.equals(OperationConstant.NOT_IN, operation)) { + wrapper.notIn(tableField, getValueCollection(value)); + } else if (Objects.equals(OperationConstant.IN, operation)) { + wrapper.in(tableField, getValueCollection(value)); + } else if (Objects.equals(OperationConstant.SORT, operation)) { + if (ObjectUtil.equal(String.valueOf(value).toUpperCase(), "DESC")) { + wrapper.orderByDesc(tableField); + } else { + wrapper.orderByAsc(tableField); + } + } else { + throw new CheckException("不支持的查询条件!"); + } + } + + private static List getValueCollection(Object value) { + Pattern valuePattern = Pattern.compile("(?<=\\().*(?=\\))"); + Matcher matcher = valuePattern.matcher(value.toString()); + if (!matcher.find()) { + throw new CheckException("集合条件value表达式不正确!"); + } + String[] values = matcher.group().split("\\|"); + return Arrays.asList(values); + } +} \ No newline at end of file diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/SearchCriteria.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/SearchCriteria.java new file mode 100644 index 0000000..3cebb82 --- /dev/null +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/SearchCriteria.java @@ -0,0 +1,25 @@ +package fun.easycode.jointblock.flexible; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * 查询条件 + * @author xuzhen97 + */ +@Data +@AllArgsConstructor +public class SearchCriteria { + /** + * 查询字段 + */ + private String key; + /** + * 查询条件 + */ + private String operation; + /** + * 查询值 + */ + private Object value; +} \ No newline at end of file diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/package-info.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/package-info.java new file mode 100644 index 0000000..a9b4a26 --- /dev/null +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/package-info.java @@ -0,0 +1,4 @@ +/** + * 灵活条件设计,特殊场景下用于替代 {@link fun.easycode.jointblock.core.DynamicOperate} + */ +package fun.easycode.jointblock.flexible; \ No newline at end of file diff --git a/pom.xml b/pom.xml index 5e6c167..55fa29f 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ 8 8 UTF-8 - 0.29.0 + 0.30.0 -- Gitee From b6469774071e1d411668f505eb75f8b70f04f5f5 Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Fri, 14 Apr 2023 16:50:36 +0800 Subject: [PATCH 02/22] =?UTF-8?q?fix:=20=E4=BF=AE=E4=B8=80=E4=B8=8B?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E6=9F=A5=E8=AF=A2=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 条件正则解析失败。 --- .../service/executor/ArticlePagingQryExeTest.java | 6 ++++-- .../flexible/QueryHandlerMethodArgumentResolver.java | 9 +++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/jointblock-spring-boot-test/src/test/java/fun/easycode/jointblock/service/executor/ArticlePagingQryExeTest.java b/jointblock-spring-boot-test/src/test/java/fun/easycode/jointblock/service/executor/ArticlePagingQryExeTest.java index eddbafb..616802c 100644 --- a/jointblock-spring-boot-test/src/test/java/fun/easycode/jointblock/service/executor/ArticlePagingQryExeTest.java +++ b/jointblock-spring-boot-test/src/test/java/fun/easycode/jointblock/service/executor/ArticlePagingQryExeTest.java @@ -25,13 +25,15 @@ public class ArticlePagingQryExeTest { public static void main(String[] args) { Pattern pattern = Pattern.compile("(\\w+?)(\\[.*\\]=)([a-zA-Z0-9\\\\u4e00-\\\\u9fa5()|]+?),"); - Matcher matcher = pattern.matcher("totalChapter[NotIn]=(6|7|8),"); + Matcher matcher = pattern.matcher("lmnid[Eq]=164044345999532823,"); Pattern operatorPattern = Pattern.compile("(?<=\\[).*(?=\\])"); +// Pattern operatorPattern = Pattern.compile("(?<=\\[).*(?=\\])"); + while (matcher.find()) { System.out.print(matcher.group(1) + " "); - System.out.print(matcher.group(2)+ " "); +// System.out.print(matcher.group(2)+ " "); Matcher operatorMatcher = operatorPattern.matcher(matcher.group(2)); diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java index 5e0523e..d76bbdf 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java @@ -40,16 +40,13 @@ public class QueryHandlerMethodArgumentResolver implements HandlerMethodArgument public static QueryWrapper buildQueryWrapper(String value, Class root) { QueryWrapperBuilder builder = new QueryWrapperBuilder(); // 整体表达式正则 - Pattern pattern = Pattern.compile("(\\w+?)(\\[.*\\]=)([a-zA-Z0-9\\\\u4e00-\\\\u9fa5]+?),"); + Pattern pattern = Pattern.compile("(\\w+?)(\\[.*\\]=)([a-zA-Z0-9\\\\u4e00-\\\\u9fa5()|]+?),"); Matcher matcher = pattern.matcher(value + ","); // 操作符匹配正则 Pattern operatorPattern = Pattern.compile("(?<=\\[).*(?=\\])"); while (matcher.find()) { - Matcher operatorMatcher = operatorPattern.matcher(matcher.group(2)); - if(!matcher.find()){ - throw new CheckException("查询条件格式错误"); - } - builder.with(matcher.group(1), operatorMatcher.group(), matcher.group(3)); + Matcher operatorMatcher = operatorPattern.matcher( matcher.group(2)); + builder.with(matcher.group(1), operatorMatcher.find() ? operatorMatcher.group() : "", matcher.group(3)); } return builder.build(root); } -- Gitee From b96231dc98d8db00515e6bdbe627c88471ef0c09 Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Fri, 14 Apr 2023 17:08:45 +0800 Subject: [PATCH 03/22] =?UTF-8?q?fix:=20=E4=BF=AE=E4=B8=80=E4=B8=8B?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E6=9F=A5=E8=AF=A2=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 条件正则解析失败。 --- .../service/executor/ArticlePagingQryExeTest.java | 6 +++--- .../flexible/QueryHandlerMethodArgumentResolver.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jointblock-spring-boot-test/src/test/java/fun/easycode/jointblock/service/executor/ArticlePagingQryExeTest.java b/jointblock-spring-boot-test/src/test/java/fun/easycode/jointblock/service/executor/ArticlePagingQryExeTest.java index 616802c..8b587f8 100644 --- a/jointblock-spring-boot-test/src/test/java/fun/easycode/jointblock/service/executor/ArticlePagingQryExeTest.java +++ b/jointblock-spring-boot-test/src/test/java/fun/easycode/jointblock/service/executor/ArticlePagingQryExeTest.java @@ -24,8 +24,8 @@ public class ArticlePagingQryExeTest { } public static void main(String[] args) { - Pattern pattern = Pattern.compile("(\\w+?)(\\[.*\\]=)([a-zA-Z0-9\\\\u4e00-\\\\u9fa5()|]+?),"); - Matcher matcher = pattern.matcher("lmnid[Eq]=164044345999532823,"); + Pattern pattern = Pattern.compile("(\\w+?)(\\[.+?\\]=)([a-zA-Z0-9\\\\u4e00-\\\\u9fa5()|]+?),"); + Matcher matcher = pattern.matcher("lmnid[Eq]=164044345999532823,status[Eq]=1,"); Pattern operatorPattern = Pattern.compile("(?<=\\[).*(?=\\])"); // Pattern operatorPattern = Pattern.compile("(?<=\\[).*(?=\\])"); @@ -33,7 +33,7 @@ public class ArticlePagingQryExeTest { while (matcher.find()) { System.out.print(matcher.group(1) + " "); -// System.out.print(matcher.group(2)+ " "); + System.out.print(matcher.group(2)+ " "); Matcher operatorMatcher = operatorPattern.matcher(matcher.group(2)); diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java index d76bbdf..60a6911 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java @@ -40,7 +40,7 @@ public class QueryHandlerMethodArgumentResolver implements HandlerMethodArgument public static QueryWrapper buildQueryWrapper(String value, Class root) { QueryWrapperBuilder builder = new QueryWrapperBuilder(); // 整体表达式正则 - Pattern pattern = Pattern.compile("(\\w+?)(\\[.*\\]=)([a-zA-Z0-9\\\\u4e00-\\\\u9fa5()|]+?),"); + Pattern pattern = Pattern.compile("(\\w+?)(\\[.+?\\]=)([a-zA-Z0-9\\\\u4e00-\\\\u9fa5()|]+?),"); Matcher matcher = pattern.matcher(value + ","); // 操作符匹配正则 Pattern operatorPattern = Pattern.compile("(?<=\\[).*(?=\\])"); -- Gitee From 38cf61ba0fe267612cd9becd29b4976112b86d15 Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Sat, 15 Apr 2023 16:51:34 +0800 Subject: [PATCH 04/22] refactor: DataFill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 彻底改变datafill的实现方式,不采用注解,应该增强代码的可读性。 --- README.md | 23 +- .../JointBlockAutoConfiguration.java | 95 ------- .../jointblock/manager/UserBaseDto.java | 2 - .../service/dto/data/ArticlePagingDto.java | 35 --- .../core/ExecutorDataFillInterceptor.java | 24 -- .../core/ExecutorDataFillPointcut.java | 47 ---- .../jointblock/datafill/DataAlias.java | 16 -- .../jointblock/datafill/DataCopy.java | 244 ------------------ .../jointblock/datafill/DataFill.java | 56 ---- .../jointblock/datafill/DataFillActuator.java | 49 ++++ .../jointblock/datafill/DataFillExecutor.java | 193 -------------- .../jointblock/datafill/DataFillId.java | 9 - .../jointblock/datafill/DataFillMetadata.java | 35 --- .../jointblock/datafill/DataFillProcess.java | 38 +++ .../datafill/DataFillProcessBuilder.java | 107 ++++++++ .../jointblock/datafill/DataFillStrategy.java | 110 -------- .../datafill/DataFillStrategyContext.java | 38 --- .../jointblock/datafill/DataFillTask.java | 51 ++-- ...nager.java => DataFillThreadExecutor.java} | 49 +--- .../jointblock/datafill/DataGenerate.java | 42 --- .../jointblock/datafill/DataParam.java | 21 -- .../jointblock/datafill/EnableDataFill.java | 13 - .../datafill/FeignDataFillStrategy.java | 130 ---------- .../easycode/jointblock/datafill/FeignId.java | 13 - .../jointblock/datafill/IDGenerateMode.java | 18 -- .../datafill/MyBatisPlusDataFillStrategy.java | 90 ------- 26 files changed, 247 insertions(+), 1301 deletions(-) delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/ExecutorDataFillInterceptor.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/ExecutorDataFillPointcut.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataAlias.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataCopy.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFill.java create mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillActuator.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillExecutor.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillId.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillMetadata.java create mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillProcess.java create mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillProcessBuilder.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillStrategy.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillStrategyContext.java rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/{DataFillThreadPoolManager.java => DataFillThreadExecutor.java} (49%) delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataGenerate.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataParam.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/EnableDataFill.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/FeignDataFillStrategy.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/FeignId.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/IDGenerateMode.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/MyBatisPlusDataFillStrategy.java diff --git a/README.md b/README.md index a110940..32aef98 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,22 @@ GeneratorConfig generatorConfig = GeneratorConfig.builder() JointBlockGenerator.generator(generatorConfig); ``` -DataFill填充框架使用必须要引入aop +DataFill填充框架使用demo -```xml - - org.springframework.boot - spring-boot-starter-aop - +```java +// 数据填充执行器 +DataFillActuator actuator = new DataFillActuator<>(billDtos); +// 中心填充处理过程 +actuator.addProcess(DataFillProcessBuilder.builder() + .keyGetFun(billDto -> billDto.getCenter().getLmnId()) + .fillDataGetFun(lmnIds -> baseDataOrgFeignClient.queryOrgPageList(DataFillProcessBuilder.request(() -> { + OrgPageQry qry = new OrgPageQry(); + qry.setLmnIdIn(lmnIds.stream().map(String::valueOf).collect(Collectors.toList())); + qry.setPageSize(9999L); + return qry; + })).getRows()) + .fillKeyGetFun(OrgDto::getLmnId) + .fillFun((billDto, orgDto) -> BeanUtil.copyProperties(orgDto, billDto.getCenter())).build()); +// 执行填充 +actuator.execute(); ``` \ No newline at end of file diff --git a/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockAutoConfiguration.java b/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockAutoConfiguration.java index 6253a77..3ede682 100644 --- a/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockAutoConfiguration.java +++ b/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockAutoConfiguration.java @@ -3,19 +3,13 @@ package fun.easycode.joinblock.autoconfigure; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import fun.easycode.jointblock.core.AuditMetaObjectHandler; import fun.easycode.jointblock.core.ExecutorContext; -import fun.easycode.jointblock.core.ExecutorDataFillInterceptor; -import fun.easycode.jointblock.core.ExecutorDataFillPointcut; -import fun.easycode.jointblock.datafill.*; import fun.easycode.jointblock.mybatisplus.JointBlockSqlInjector; import lombok.extern.slf4j.Slf4j; -import org.springframework.aop.Advisor; -import org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; @@ -65,11 +59,6 @@ public class JointBlockAutoConfiguration implements BeanFactoryAware{ return new JointBlockSqlInjector(); } - @Bean - public DataCopy dataCopy(){ - return new DataCopy(); - } - /** * mybatis plus审计字段处理 * @return AuditMetaObjectHandler @@ -80,41 +69,6 @@ public class JointBlockAutoConfiguration implements BeanFactoryAware{ return new AuditMetaObjectHandler(); } - /** - * 代码填充织入执行器 - * @return DefaultBeanFactoryPointcutAdvisor - */ - @ConditionalOnClass(Advisor.class) - @Bean - public DefaultBeanFactoryPointcutAdvisor executorDataFillAdvisor() { - // 自动填充织入到Executor.execute方法 - DefaultBeanFactoryPointcutAdvisor advisor = new DefaultBeanFactoryPointcutAdvisor(); - advisor.setPointcut(executorDataFillPointcut()); - advisor.setAdvice(executorDataFillInterceptor()); - advisor.setBeanFactory(beanFactory); - return advisor; - } - - /** - * 执行器识别定义的切点 - * @return ExecutorDataFillPointcut - */ - @Bean - @ConditionalOnClass(Advisor.class) - public ExecutorDataFillPointcut executorDataFillPointcut(){ - return new ExecutorDataFillPointcut(); - } - - /** - * 执行器数据填充具体的切入逻辑 - * @return ExecutorDataFillInterceptor - */ - @Bean - @ConditionalOnClass(Advisor.class) - public ExecutorDataFillInterceptor executorDataFillInterceptor(){ - return new ExecutorDataFillInterceptor(); - } - /** * 执行器上下文,用于直接获取执行器进行调用 * @return ExecutorContext @@ -124,55 +78,6 @@ public class JointBlockAutoConfiguration implements BeanFactoryAware{ return new ExecutorContext(); } - // 下方是DataFill的配置 - - /** - * mybatis plus填充策略支持 - * @return MyBatisPlusDataFillStrategy - */ - @Bean - @ConditionalOnClass({BaseMapper.class}) - public MyBatisPlusDataFillStrategy myBatisPlusDataFillStrategy(){ - return new MyBatisPlusDataFillStrategy(); - } - - /** - * feign远程调用策略支持 - * @return FeignDataFillStrategy - */ - @Bean - @ConditionalOnClass(name = "org.springframework.cloud.openfeign.FeignContext") - public FeignDataFillStrategy feignDataFillStrategy(){ - return new FeignDataFillStrategy(); - } - - /** - * 数据填充具体执行器, 这里与业务执行器没有联系 - * @return DataFillExecutor - */ - @Bean - public DataFillExecutor dataFillExecutor(){ - return new DataFillExecutor(); - } - - /** - * 数据填充策略Context, 用于获取填充策略 - * @return DataFillStrategyContext - */ - @Bean - public DataFillStrategyContext dataFillStrategyContext(){ - return new DataFillStrategyContext(); - } - - /** - * 数据填充线程池管理 - * @return DataFillThreadPoolManager - */ - @Bean - public DataFillThreadPoolManager dataFillThreadPoolManager(){ - return new DataFillThreadPoolManager(); - } - @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; diff --git a/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/manager/UserBaseDto.java b/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/manager/UserBaseDto.java index 7ed3436..5671601 100644 --- a/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/manager/UserBaseDto.java +++ b/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/manager/UserBaseDto.java @@ -1,7 +1,6 @@ package fun.easycode.jointblock.manager; -import fun.easycode.jointblock.datafill.FeignId; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -15,7 +14,6 @@ import java.io.Serializable; @NoArgsConstructor public class UserBaseDto implements Serializable { - @FeignId private String userId; private String nickname; private String avatar; diff --git a/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/service/dto/data/ArticlePagingDto.java b/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/service/dto/data/ArticlePagingDto.java index 40b4155..e4d8f46 100644 --- a/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/service/dto/data/ArticlePagingDto.java +++ b/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/service/dto/data/ArticlePagingDto.java @@ -1,15 +1,11 @@ package fun.easycode.jointblock.service.dto.data; -import fun.easycode.jointblock.datafill.DataFill; -import fun.easycode.jointblock.datafill.DataParam; -import fun.easycode.jointblock.datafill.EnableDataFill; import fun.easycode.jointblock.manager.*; import lombok.Data; import java.util.List; @Data -@EnableDataFill public class ArticlePagingDto { private String id; private String title; @@ -19,45 +15,14 @@ public class ArticlePagingDto { private List img; private List coverImgSmall; // , methodName = "getUserByIds" - @DataFill(source = UserClient.class, value = "userId") private UserBaseDto user; - @DataFill(source = CollegeClient.class) private CollegeDto college; private Long createTime; - @DataFill(source = PraiseCountClient.class) private int praiseCount; - @DataFill(source = CommentCountClient.class, params = { - @DataParam( - name = "topicIds", - value = "#ids" - ) - }) private int commentCount; - @DataFill(source = BroweCountClient.class - , spEl = "#source.playAmount + #source.virtualPlayAmount") private int browseCount; - @DataFill(source = PraiseClient.class, params = { - @DataParam( - name = "userId", - value = "T(fun.easycode.jointblock.common.util.SecurityUtil).getCurrentUserId()" - ), - @DataParam( - name = "topicIds", - value = "#ids" - ) - }) private Boolean isPraise = false; private Boolean isAttention = false; - @DataFill(source = FavoriteClient.class, params = { - @DataParam( - name = "userId", - value = "T(fun.easycode.jointblock.common.util.SecurityUtil).getCurrentUserId()" - ), - @DataParam( - name = "topicIds", - value = "#ids" - ) - }) private Boolean isCollection = false; private String topicType = TopicType.ARTICLE.getValue(); private String type = WorkType.TEXT.getValue(); diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/ExecutorDataFillInterceptor.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/ExecutorDataFillInterceptor.java deleted file mode 100644 index 2fb1208..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/ExecutorDataFillInterceptor.java +++ /dev/null @@ -1,24 +0,0 @@ -package fun.easycode.jointblock.core; - -import fun.easycode.jointblock.datafill.DataFillExecutor; -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; - -import javax.annotation.Resource; - -/** - * interceptor 用于数据填充 - * @author xuzhe - */ -public class ExecutorDataFillInterceptor implements MethodInterceptor { - - @Resource - private DataFillExecutor dataFillExecutor; - - @Override - public Object invoke(MethodInvocation methodInvocation) throws Throwable { - Object result = methodInvocation.proceed(); - dataFillExecutor.execute(result); - return result; - } -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/ExecutorDataFillPointcut.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/ExecutorDataFillPointcut.java deleted file mode 100644 index b46e1fc..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/ExecutorDataFillPointcut.java +++ /dev/null @@ -1,47 +0,0 @@ -package fun.easycode.jointblock.core; - -import cn.hutool.core.util.ClassUtil; -import org.springframework.aop.ClassFilter; -import org.springframework.aop.MethodMatcher; -import org.springframework.aop.Pointcut; - -import java.lang.reflect.Method; -import java.util.Objects; - -/** - * 自定义aop切点 - * 当是Executor时切入,execute时执行逻辑 - * @author xuzhe - */ -public class ExecutorDataFillPointcut implements Pointcut { - @Override - public ClassFilter getClassFilter() { - return new ClassFilter() { - @Override - public boolean matches(Class aClass) { - - return ClassUtil.isAssignable(Executor.class, aClass); - } - }; - } - - @Override - public MethodMatcher getMethodMatcher() { - return new MethodMatcher() { - @Override - public boolean matches(Method method, Class aClass) { - return Objects.equals("execute", method.getName()); - } - - @Override - public boolean isRuntime() { - return false; - } - - @Override - public boolean matches(Method method, Class aClass, Object... objects) { - return false; - } - }; - } -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataAlias.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataAlias.java deleted file mode 100644 index d023b0b..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataAlias.java +++ /dev/null @@ -1,16 +0,0 @@ -package fun.easycode.jointblock.datafill; - -import java.lang.annotation.*; - -/** - * @author xuzhe - */ -@Target({ElementType.FIELD,ElementType.ANNOTATION_TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface DataAlias { - /** - * 实体的主键名, 默认id - */ - String value(); -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataCopy.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataCopy.java deleted file mode 100644 index ef73b9f..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataCopy.java +++ /dev/null @@ -1,244 +0,0 @@ -package fun.easycode.jointblock.datafill; - -import cn.hutool.core.util.ReflectUtil; -import fun.easycode.jointblock.core.PageDto; -import fun.easycode.jointblock.exception.CheckException; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.expression.EvaluationContext; -import org.springframework.expression.Expression; -import org.springframework.expression.ExpressionParser; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; -import org.springframework.util.StringUtils; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; -import java.util.*; - -/** - * @author xuzhe - */ -public class DataCopy implements ApplicationContextAware { - - private static ApplicationContext context; - private ExpressionParser expressionParser; - - /** - * 解析spEl表达式, 传输两个对象source 和 target 到上下文 - * @param source - * @param target - * @param spEl - * @param tClass - * @return - * @param - */ - public Optional parserSpEl(Object source, Object target, String spEl, Class tClass){ - if(StringUtils.isEmpty(spEl)){ - return Optional.empty(); - } - EvaluationContext evaluationContext = new StandardEvaluationContext(context); - evaluationContext.setVariable("source", source); - evaluationContext.setVariable("target", target); - Expression expression = expressionParser.parseExpression(spEl); - return Optional.ofNullable(expression.getValue(evaluationContext, tClass)); - } - - /** - * 解析spEl表达式 - * @param spEl - * @param tClass - * @return - * @param - */ - public Optional parserSpEl(String spEl, Class tClass){ - if(StringUtils.isEmpty(spEl)){ - return Optional.empty(); - } - EvaluationContext evaluationContext = new StandardEvaluationContext(context); - Expression expression = expressionParser.parseExpression(spEl); - return Optional.ofNullable(expression.getValue(evaluationContext, tClass)); - } - - /** - * 解析spEl表达式,允许往上下文传输contextProps变量列表,供用户使用 - * @param spEl - * @param tClass - * @param contextProps - * @return - * @param - */ - public Optional parserSpEl(String spEl, Class tClass,final Map contextProps){ - if(StringUtils.isEmpty(spEl)){ - return Optional.empty(); - } - EvaluationContext evaluationContext = new StandardEvaluationContext(context); - if(contextProps != null){ - contextProps.forEach((key,value)->{ - evaluationContext.setVariable(key, value); - }); - } - Expression expression = expressionParser.parseExpression(spEl); - return Optional.ofNullable(expression.getValue(evaluationContext, tClass)); - } - - /** - * 对象属性copy - * 方法支持使用@DataAlias注解进行转义 - * 例如目标中叫做id ,但是在source中叫做userId - * 那么我们可以在目标中增加注解@DataAlias("userId")来进行对接 - * - * @param source 元对象 - * @param target 目标对象 - */ - @SuppressWarnings("all") - public void copy(Object source, Object target, String spEl) { - - Map sourceFieldMap = ReflectUtil.getFieldMap(source.getClass()); - Map targetFieldMap = ReflectUtil.getFieldMap(target.getClass()); - - for (Map.Entry targetEntry : targetFieldMap.entrySet()) { - Field targetField = targetEntry.getValue(); - String targetFieldName; - if (targetField.isAnnotationPresent(DataAlias.class)) { - DataAlias dataAlias = targetField.getAnnotation(DataAlias.class); - targetFieldName = dataAlias.value(); - } else { - targetFieldName = targetEntry.getKey(); - } - - Field sourceField = sourceFieldMap.get(targetFieldName); - - // 如果source和target对象,属性值能直接匹配的话,就直接copy - if (sourceField != null) { - Object value = ReflectUtil.getFieldValue(source, sourceField); - ReflectUtil.setFieldValue(target, targetField, value); - } - // 如果target对象中的属性是一个完整的对象,或者list, 就需要增加DataGenerate处理 - // 要知道如果我们对象很简单数据填充的时候只需要mapstruct将id转换成空对象即可 - // 但是超过两层结构,我们的数据其实还没有加载,那么就需要DataGenerate来进行解决了 - else if (targetField.isAnnotationPresent(DataGenerate.class)) { - DataGenerate dataGenerate = targetField.getAnnotation(DataGenerate.class); - - sourceField = sourceFieldMap.get(dataGenerate.value()); - Object sourceFieldValue = ReflectUtil.getFieldValue(source, sourceField); - - // 如果是id生成的默认形式,会根据我们声明的目标对象类型,生成空对象 - // 然后去source对象中去取指定的属性值填充到空对象内 - // 通俗的讲 就是id属性转换成一个对象,对象中仅仅id属性有值 - if (dataGenerate.mode() == IDGenerateMode.DEFAULT) { - // 根据要生成空对象的Field生成实例 - Object targetFieldValue = ReflectUtil.newInstance(targetField.getType()); - - // 生成实例后将主键信息填写进去 - Field subTargetField = ReflectUtil.getField(targetFieldValue.getClass() - , dataGenerate.targetField()); - - if (targetField != null) { - ReflectUtil.setFieldValue(targetFieldValue, subTargetField, sourceFieldValue); - } - ReflectUtil.setFieldValue(target, targetField, targetFieldValue); - - } else if (dataGenerate.mode() == IDGenerateMode.MULTIPLE - && dataGenerate.listClass() != void.class) { - // 这里主要是处理数据库中一个字段存了多个id类似 aa,bb,cc这种 - // 而我们需要将多个id生成为list集合, 方便填充框架下一步工作 - String idsStr = (String) sourceFieldValue; - // 数据库的主键分割 - List ids = Arrays.asList(idsStr.split(dataGenerate.listSeparator())); - List list = new ArrayList(); - for (String id : ids) { - Object targetFieldValue = ReflectUtil.newInstance(dataGenerate.listClass()); - // 生成实例后将主键信息填写进去 - Field subTargetField = ReflectUtil.getField(targetFieldValue.getClass() - , dataGenerate.targetField()); - - if (subTargetField != null) { - ReflectUtil.setFieldValue(targetFieldValue, targetField, id); - } - list.add(targetFieldValue); - } - ReflectUtil.setFieldValue(target, targetField, list); - } - } - } - // 如果非基本类型定义了el表达式,不会取返回参数,会执行用户自定义的逻辑 - if(!StringUtils.isEmpty(spEl)){ - parserSpEl(source, target, spEl, Void.class); - } - } - - public Object getMapObjById(Object id, Map map){ - return map.get(id); - } - - public Object getPageDtoById(Object id , PageDto result - , Class idAnnotation){ - return getCollectionObjById(id, result.getData(), idAnnotation); - } - - public Object getObjById(Object id, Object container, Class idAnnotation){ - if(container instanceof Map){ - return getMapObjById(id, (Map) container); - }else if (container instanceof Collection){ - return getCollectionObjById(id, (Collection) container, idAnnotation); - }else if(container instanceof PageDto){ - return getPageDtoById(id, (PageDto) container, idAnnotation); - }else{ - throw new CheckException("不支持的容器!"); - } - } - - /** - * 根据id获取List中符合的元素 - * 默认取id的列对比,如果没有叫做id的列则取@TableId的列对比 - * @param id - * @param collection - * @param idAnnotation 如果id不是主键默认名称,应该以什么注解进行判断 - * @return - */ - @SuppressWarnings("all") - public Object getCollectionObjById(Object id, Collection collection, Class idAnnotation){ - - if(collection == null || collection.size() == 0){ - return null; - } - - Class elementClass = collection.stream().findFirst().get().getClass(); - Map fieldMap = ReflectUtil.getFieldMap(elementClass); - - Field field = fieldMap.get("id"); - - if(field == null){ - - Optional first = fieldMap.values() - .stream() - .filter(f -> f.isAnnotationPresent(idAnnotation)) - .findFirst(); - - field = first.isPresent()?first.get():null; - - if(field == null){ - throw new CheckException(elementClass.getName() + "请增加注解" + idAnnotation.getName()+"标记主键!"); - } - } - - final Field conditionField = field; - - Optional first = collection.stream().filter(obj -> Objects.equals(id, ReflectUtil.getFieldValue(obj, conditionField))) - .findFirst(); - - return first.isPresent()?first.get():null; - } - - public static DataCopy getInstance(){ - return context.getBean(DataCopy.class); - } - - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - context = applicationContext; - expressionParser = new SpelExpressionParser(); - } -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFill.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFill.java deleted file mode 100644 index f11ff5a..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFill.java +++ /dev/null @@ -1,56 +0,0 @@ -package fun.easycode.jointblock.datafill; - -import java.lang.annotation.*; - -/** - * @author xuzhe - */ -@Target({ElementType.FIELD,ElementType.ANNOTATION_TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface DataFill { - /** - * 实体的主键名, 默认id - * @return id字段名 - */ - String value() default "id"; - - /** - * 注解对应处理器 - * @return 对应的处理器 - */ - Class source(); - - /** - * spring el表达式 - * 如果我们自定义表达式 - * 当DataFill所在基本数据类型的时候spEl表达式的值是最终填充的值 - * 所在属性是对象,或者是list的时候,表达式不取返回值 - * 我们可以在Mapstruct转换器中自定义处理逻辑 - * 固定会传入target对象和source对象,target对象就是当前属性的值 - * List的话就是其中的对象,source是id查出的对应实体 - * @return 我们自定义的逻辑 - */ - String spEl() default ""; - - /** - * 自定义传参 - * DataParam value支持el表达式 - * @return 参数列表 - */ - DataParam[] params() default {}; - - /** - * 自定义调用方法名,目前仅对feign client生效 - * 如果不指定方法名,那么在feign client的指定中,client只能存在一个方法 - * @return 方法名 - */ - String methodName() default ""; - - /** - * 是否自定义mybatis plus id注解 - * @Author: xuzhen97 - * @Date: 2023/03/17 - */ - boolean isCustomMyBatisPlusAnno() default false; -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillActuator.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillActuator.java new file mode 100644 index 0000000..a32b7c5 --- /dev/null +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillActuator.java @@ -0,0 +1,49 @@ +package fun.easycode.jointblock.datafill; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 数据填充执行器 + * @param 数据类型 + */ +public class DataFillActuator { + // 数据 + private final Collection data; + // 填充过程 + private final List> processes = new ArrayList<>(); + + /** + * 构造函数 + * @param data 数据 + */ + public DataFillActuator(Collection data) { + this.data = data; + } + + /** + * 增加填充过程 + * @param process 填充过程 + */ + public DataFillActuator addProcess(DataFillProcess process) { + processes.add(process); + return this; + } + + /** + * 执行 + */ + public void execute() { + List> tasks = processes.stream() + .map(process -> new DataFillTask<>(process, data)) + .collect(Collectors.toList()); + try { + // 执行任务 + DataFillThreadExecutor.execParallelTasks(tasks); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillExecutor.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillExecutor.java deleted file mode 100644 index 4a363e7..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillExecutor.java +++ /dev/null @@ -1,193 +0,0 @@ -package fun.easycode.jointblock.datafill; - -import cn.hutool.core.util.ClassUtil; -import cn.hutool.core.util.HashUtil; -import cn.hutool.core.util.ReflectUtil; -import fun.easycode.jointblock.core.PageDto; -import fun.easycode.jointblock.exception.CheckException; -import lombok.extern.slf4j.Slf4j; - -import java.lang.reflect.Field; -import java.util.*; -import java.util.stream.Collectors; - -/** - * 数据填充工厂 - * - * @author xuzhe - */ -@Slf4j -public class DataFillExecutor { - - /** - * 填充框架执行 - * - * @param o 填充对象 - */ - public void execute(Object o) { - List metadataList = new ArrayList<>(); - fetch(o, metadataList); - executeMetaDataList(metadataList); - } - - private void executeMetaDataList(List metadataList) { - - executeDataFill(metadataList); - List metadataListSub = new ArrayList<>(); - - for (DataFillMetadata metadata : metadataList) { - fetch(metadata.getTargetObjMap().values(), metadataListSub); - } - if (metadataListSub.size() > 0) { - executeMetaDataList(metadataListSub); - } - } - - private void executeDataFill(List metadataList) { - //异步任务 - List>> tasks = new ArrayList<>(); - - // 现根据sourceClass进行分组 - // 实际上就是BaseMapper或者FeignContract的实现 - // 其它实现不支持,默认不处理 - Map, List> anClassMetadatas = metadataList.stream() - .collect(Collectors.groupingBy(dataFillMetadata -> dataFillMetadata.getDataFill().source())); - - // 根据params hash 进行group分组生成task - anClassMetadatas.forEach((sourceClass, sourceClassMetadataList) -> { - sourceClassMetadataList.stream().collect(Collectors.groupingBy(this::hashParams)).values() - .forEach(hashMetadataList -> { - DataFillStrategyContext.getStrategy(sourceClass).ifPresent(strategy -> { - tasks.add(new DataFillTask<>(strategy, hashMetadataList)); - }); - }); - }); - - try { - DataFillThreadPoolManager.execParallelTasks(tasks); - } catch (Exception e) { - e.printStackTrace(); - } - } - - /** - * 填充信息拉取 - * - * @param o 处理对象 - * @param metadataList 元数据集合 - */ - @SuppressWarnings("all") - private void fetch(Object o, List metadataList) { - if (o == null || metadataList == null) { - return; - } - if (o instanceof Collection) { - for (Object o1 : ((Collection) o)) { - fetch(o1, metadataList); - } - } else if (o instanceof Map) { - for (Object value : ((Map) o).values()) { - fetch(value, metadataList); - } - } else if (o instanceof PageDto) { - PageDto pageDto = (PageDto) o; - fetch(pageDto.getData(), metadataList); - } else { - Class oClass = o.getClass(); - // 这里抛出的异常其最终目的就是中断当前集合的遍历, - // 如果集合容器中第一个节点到达这里并判断没有填充标识,则当前容器就不需要在继续遍历下去了 - if (oClass.getAnnotation(EnableDataFill.class) == null) { - return; - } - - // 如果传入操作对象是基本数据类型或者String不进行下面的逻辑 - if (ClassUtil.isBasicType(oClass) - || oClass.isAssignableFrom(String.class)) { - return; - } - - Map fieldMap = ReflectUtil.getFieldMap(oClass); - - for (Map.Entry entry : fieldMap.entrySet()) { - - Field field = entry.getValue(); - - // 非基本类型而且拥有DataFill的注解才代表需要处理 - DataFill dataFill = field.getAnnotation(DataFill.class); - - // 字段上未增加DataFill注解,代表字段不需要处理 - if (dataFill == null) { - continue; - } - - Object fieldValue = ReflectUtil.getFieldValue(o, field); - - if (ClassUtil.isBasicType(field.getType()) - || field.getType().isAssignableFrom(String.class)) { - // 基本类型或者String 给fieldValue复制null, 方便下边的判断 - fieldValue = null; - } else { - if (fieldValue == null) { - continue; - } - } - - DataFillMetadata dataFillMetadata = new DataFillMetadata(); - dataFillMetadata.setDataFill(dataFill); - dataFillMetadata.setOpObj(o); - dataFillMetadata.setOpField(field); - - Map targetObjMap = new HashMap<>(); - - // DataFill可以依附的对象 - // - Collection - // - 普通对象 - // - 基本类型 - if (fieldValue == null) { - // 如果要操作的field是基本数据类型或者String - // 对象或者List都是去对象、List内对象里面的主键属性 - // 但是基本数据类型取的是opObj操作对象的属性 - // 这里是结合上面的判断得出的fieldValue == null 是基本数据类型或者String - Field primaryKeyField = fieldMap.get(dataFill.value()); - Object primaryKeyValue = ReflectUtil.getFieldValue(o, primaryKeyField); - targetObjMap.put(primaryKeyValue, null); - } else if (fieldValue instanceof Collection) { - for (Object targetObj : (Collection) fieldValue) { - Field primaryKeyField = ReflectUtil.getField(targetObj.getClass(), dataFill.value()); - Object primaryKeyValue = ReflectUtil.getFieldValue(targetObj, primaryKeyField); - targetObjMap.put(primaryKeyValue, targetObj); - } - } else { - // 如果是普通对象 - Field primaryKeyField = ReflectUtil.getField(fieldValue.getClass(), dataFill.value()); - Object primaryKeyValue = ReflectUtil.getFieldValue(fieldValue, primaryKeyField); - - targetObjMap.put(primaryKeyValue, fieldValue); - } - - dataFillMetadata.setTargetObjMap(targetObjMap); - - metadataList.add(dataFillMetadata); - } - } - } - - /** - * 根据DataParam[] 参数列表计算一个hash - * 用于分组,不同的条件需要不同的查询 - * - * @param metadata DataFillMetadata - * @return long hash - */ - public long hashParams(DataFillMetadata metadata) { - DataParam[] params = metadata.getDataFill().params(); - Map paramMap = Arrays.stream(params) - .collect(Collectors.toMap(DataParam::name, p -> p)); - - List paramNameList = Arrays.stream(params).map(DataParam::name) - .sorted().collect(Collectors.toList()); - String grouping = paramNameList.stream().map(paramName -> paramName + paramMap.get(paramName)) - .collect(Collectors.joining()); - return HashUtil.mixHash(grouping); - } -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillId.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillId.java deleted file mode 100644 index 4f27c1b..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillId.java +++ /dev/null @@ -1,9 +0,0 @@ -package fun.easycode.jointblock.datafill; - -import java.lang.annotation.*; - -@Target({ElementType.FIELD,ElementType.ANNOTATION_TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface DataFillId { -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillMetadata.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillMetadata.java deleted file mode 100644 index 5a0ccbf..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillMetadata.java +++ /dev/null @@ -1,35 +0,0 @@ -package fun.easycode.jointblock.datafill; - -import lombok.Data; - -import java.lang.reflect.Field; -import java.util.Map; - -/** - * 元数据填充类型 - * @author xuzhe - */ -@Data -public class DataFillMetadata { - - /** - * 数据填充操作对象 - */ - private Object opObj; - /** - * 数据填充操作属性 - */ - private Field opField; - - /** - * 数据填充目标对象 - * key = 主键 - * value = 仅有主键属性的空对象 - */ - private Map targetObjMap; - - /** - * 数据填充操作属性上标注的@DataFill注解 - */ - private DataFill dataFill; -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillProcess.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillProcess.java new file mode 100644 index 0000000..92eaae1 --- /dev/null +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillProcess.java @@ -0,0 +1,38 @@ +package fun.easycode.jointblock.datafill; + +import lombok.Getter; + +import java.util.Collection; +import java.util.function.BiConsumer; +import java.util.function.Function; + +/** + * 数据填充过程 + * @author xuzhen97 + */ +@Getter +public class DataFillProcess { + + // key获取函数 + private final Function keyGetFun; + // 填充数据获取函数 + private final Function, Collection> fillDataGetFun; + // 填充数据key获取函数 + private final Function fillKeyGetFun; + // 填充函数 + private final BiConsumer fillFun; + + /** + * 构造函数 + * @param keyGetFun key获取函数 + * @param fillDataGetFun 填充数据获取函数 + * @param fillKeyGetFun 填充数据key获取函数 + * @param fillFun 填充函数 + */ + protected DataFillProcess(Function keyGetFun, Function, Collection> fillDataGetFun, Function fillKeyGetFun, BiConsumer fillFun) { + this.keyGetFun = keyGetFun; + this.fillDataGetFun = fillDataGetFun; + this.fillKeyGetFun = fillKeyGetFun; + this.fillFun = fillFun; + } +} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillProcessBuilder.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillProcessBuilder.java new file mode 100644 index 0000000..541df79 --- /dev/null +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillProcessBuilder.java @@ -0,0 +1,107 @@ +package fun.easycode.jointblock.datafill; + +import cn.hutool.core.util.ReflectUtil; + +import java.util.Collection; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * 数据填充过程构建器 + * @param 数据类型 + * @param 填充逻辑远程返回的数据类型 + * @author xuzhen97 + */ +public class DataFillProcessBuilder { + + // key获取函数 + private Function keyGetFun; + // 填充数据获取函数 + private Function, Collection> fillDataGetFun; + // 填充数据key获取函数 + private Function fillKeyGetFun; + // 填充函数 + private BiConsumer fillFun; + + /** + * 设置key获取函数 + * @param keyGetFun key获取函数 + * @return this + */ + public DataFillProcessBuilder keyGetFun(Function keyGetFun) { + this.keyGetFun = keyGetFun; + return this; + } + + /** + * 设置填充数据获取函数 + * @param fillDataGetFun 填充数据获取函数 + * @return this + */ + public DataFillProcessBuilder fillDataGetFun(Function, Collection> fillDataGetFun) { + this.fillDataGetFun = fillDataGetFun; + return this; + } + + /** + * 设置填充数据key获取函数 + * @param fillKeyGetFun 填充数据key获取函数 + * @return this + */ + public DataFillProcessBuilder fillKeyGetFun(Function fillKeyGetFun) { + this.fillKeyGetFun = fillKeyGetFun; + return this; + } + + /** + * 设置填充函数 + * @param fillFun 填充函数 + * @return this + */ + public DataFillProcessBuilder fillFun(BiConsumer fillFun) { + this.fillFun = fillFun; + return this; + } + + /** + * 构建 + * @return 数据填充过程 + */ + public DataFillProcess build() { + if (keyGetFun == null) { + throw new IllegalArgumentException("keyGetFun不能为空"); + } + if (fillDataGetFun == null) { + throw new IllegalArgumentException("fillDataGetFun不能为空"); + } + if(fillKeyGetFun == null){ + // 默认使用id字段 + fillKeyGetFun = e -> ReflectUtil.getFieldValue(e, "id"); + } + if (fillFun == null) { + throw new IllegalArgumentException("fillFun不能为空"); + } + return new DataFillProcess<>(keyGetFun, fillDataGetFun,fillKeyGetFun, fillFun); + } + + /** + * 获取构建器 + * @param 数据类型 + * @param 填充逻辑远程返回的数据类型 + * @return 构建器 + */ + public static DataFillProcessBuilder builder() { + return new DataFillProcessBuilder<>(); + } + + /** + * 请求, 简化填充写法 + * @param supplier 请求函数 + * @param 返回类型 + * @return 返回值 + */ + public static RE request(Supplier supplier){ + return supplier.get(); + } +} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillStrategy.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillStrategy.java deleted file mode 100644 index 0268ee6..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillStrategy.java +++ /dev/null @@ -1,110 +0,0 @@ -package fun.easycode.jointblock.datafill; - -import cn.hutool.core.util.ClassUtil; -import cn.hutool.core.util.ReflectUtil; -import org.springframework.util.StringUtils; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Field; -import java.util.List; -import java.util.Optional; - -/** - * 数据填充策略 - * - * @author xuzhe - */ -public interface DataFillStrategy { - - /** - * 填充逻辑 - * - * @param metadataList 元数据集合 - */ - void fill(List metadataList); - - /** - * 获取可以处理的类型Class - * - * @return Class - */ - default Class getType() { - return void.class; - } - - /** - * 获取注解,数据源对象上增加注解也可以 - * @return - */ - default Class getAnnotation(){ - return null; - } - - /** - * 基本数据类型set逻辑 - * @param metadata - * @param container - * @param ofAnnoClass - * @param - */ - default void basicTypeSet(DataFillMetadata metadata, Object container , Class ofAnnoClass){ - Object primaryKey = metadata.getTargetObjMap().keySet().stream().findFirst().get(); - Object databaseObj = DataCopy.getInstance().getObjById(primaryKey, container, ofAnnoClass); - - // 查找不到填充对象则本地处理结束 - if(databaseObj == null){ - return; - } - - // 如果返回值是基本数据类型那么就直接就是值 - if(ClassUtil.isBasicType(databaseObj.getClass()) - || databaseObj.getClass().isAssignableFrom(String.class)){ - ReflectUtil.setFieldValue(metadata.getOpObj(), metadata.getOpField(), databaseObj); - }else { - - Object value = null; - - // 如果用户自定义了spEl表达式,那么完全以el表达式的结果作为value - // 如果没有定义spEl表达式则查找同名的属性进行填充 - if (!StringUtils.isEmpty(metadata.getDataFill().spEl())) { - Optional valueOptional = DataCopy.getInstance().parserSpEl( - databaseObj, - null, - metadata.getDataFill().spEl(), - metadata.getOpField().getType()); - value = valueOptional.orElse(null); - } else { - Field databaseObjField = ReflectUtil.getField(databaseObj.getClass() - , metadata.getOpField().getName()); - - if (databaseObjField != null) { - value = ReflectUtil.getFieldValue(databaseObj, databaseObjField); - } - } - ReflectUtil.setFieldValue(metadata.getOpObj(), metadata.getOpField(), value); - } - } - - /** - * 处理返回结构 - * @param metadata 元数据 - * @param container 数据源查询后返回的容器,就是list或者map - * @param idAnno 当返回的数据主键不是id的时候,用什么注解进行的标注 - */ - default void handlerResult(DataFillMetadata metadata, Object container, Class idAnno){ - // 如果目标对象是基本类型,我们直接去找source中有没有重名的属性 - // 有就取值 - if (ClassUtil.isBasicType(metadata.getOpField().getType()) - || metadata.getOpField().getType().isAssignableFrom(String.class)) { - basicTypeSet(metadata, container, idAnno); - }else{ - metadata.getTargetObjMap().forEach((key, value) -> { - Object databaseObj = DataCopy.getInstance().getObjById(key, container, idAnno); - if (databaseObj != null) { - DataCopy.getInstance().copy(databaseObj - , value, metadata.getDataFill().spEl()); - } - }); - } - } -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillStrategyContext.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillStrategyContext.java deleted file mode 100644 index 2ae407f..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillStrategyContext.java +++ /dev/null @@ -1,38 +0,0 @@ -package fun.easycode.jointblock.datafill; - -import cn.hutool.core.util.ClassUtil; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; - -import java.util.Map; -import java.util.Optional; - -/** - * 填充策略Context - * @author xuzhe - */ -public class DataFillStrategyContext implements ApplicationContextAware { - - // 实际上这里的key无用,因为判断条件需要ClassUtil.isAssignable判断 - // 并不是一个简单的key - private static Map strategies; - - /** - * 获取策略,就是根据DataFill上面的class - * @param type 类型 - * @return 填充策略 - */ - public static Optional getStrategy(Class type){ - // 填充策略寻找规则,注解和type的方式只要有一种即可 - return strategies.values().stream() - .filter(sgy -> (sgy.getAnnotation() != null && type.isAnnotationPresent(sgy.getAnnotation())) - || (sgy.getType() != void.class && ClassUtil.isAssignable(sgy.getType(), type))) - .findFirst(); - } - - @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { - DataFillStrategyContext.strategies = context.getBeansOfType(DataFillStrategy.class); - } -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillTask.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillTask.java index 8aedf6f..6eae579 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillTask.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillTask.java @@ -2,35 +2,46 @@ package fun.easycode.jointblock.datafill; import lombok.extern.slf4j.Slf4j; +import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.concurrent.Callable; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.stream.Collectors; /** * 数据框架填充任务 - * @author xuzhe + * @author xuzhen97 */ @Slf4j -public class DataFillTask implements Callable> { +public class DataFillTask implements Callable { - private final DataFillStrategy strategy; - private final List metadataList; + private final DataFillProcess process; + private final Collection data; - public DataFillTask(DataFillStrategy handler, List metadataList){ - this.strategy = handler; - this.metadataList = metadataList; - } - - @Override - public List call() { - try { - strategy.fill(metadataList); - }catch (Exception e){ - if(log.isDebugEnabled()) { - e.printStackTrace(); - } - log.error(e.getMessage()); + public DataFillTask(DataFillProcess process, Collection data) { + this.process = process; + this.data = data; } - return null; - } + @Override + public Void call() throws Exception { + Function keyGetFun = process.getKeyGetFun(); + Function, Collection> fillDataGetFun = process.getFillDataGetFun(); + Function fillKeyGetFun = process.getFillKeyGetFun(); + BiConsumer fillFun = process.getFillFun(); + // 获取keys + List keys = data.stream().map(keyGetFun).collect(Collectors.toList()); + // 获取填充数据 + Collection fillData = fillDataGetFun.apply(keys); + // 处理填充数据成key map 方便查找 + Map idFillDataMap = fillData.stream().collect(Collectors.toMap(fillKeyGetFun, e -> e)); + // 填充数据 + data.stream().filter(d-> idFillDataMap.containsKey(keyGetFun.apply(d))).forEach(d -> { + E e = idFillDataMap.get(keyGetFun.apply(d)); + fillFun.accept(d, e); + }); + return null; + } } diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillThreadPoolManager.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillThreadExecutor.java similarity index 49% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillThreadPoolManager.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillThreadExecutor.java index 7d36e6d..668353c 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillThreadPoolManager.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataFillThreadExecutor.java @@ -1,9 +1,6 @@ package fun.easycode.jointblock.datafill; import com.alibaba.ttl.TtlCallable; -import lombok.extern.slf4j.Slf4j; -import org.springframework.jmx.export.annotation.ManagedAttribute; -import org.springframework.jmx.export.annotation.ManagedOperation; import java.util.Collection; import java.util.List; @@ -11,13 +8,13 @@ import java.util.concurrent.*; import java.util.stream.Collectors; /** - * @author xuzhe + * 数据填充线程池 + * @author xuzhen97 */ -@Slf4j -public class DataFillThreadPoolManager { +public final class DataFillThreadExecutor { /** - * 异步任务线程池,最大队列数,无需即使性 + * 异步任务线程池,最大队列数,无需及时返回的任务,请使用此线程池 */ public static final ThreadPoolExecutor executor = new ThreadPoolExecutor(50 @@ -27,42 +24,6 @@ public class DataFillThreadPoolManager { , new LinkedBlockingQueue<>() , new ThreadPoolExecutor.AbortPolicy()); - @ManagedAttribute - public int getCorePoolSize() { - return executor.getCorePoolSize(); - } - - @ManagedAttribute - public int getMaximumPoolSize(){ - return executor.getMaximumPoolSize(); - } - - /** - * 设置线程池初始数量 - * @param corePoolSize 初始数量 - */ - @ManagedAttribute - public void setCorePoolSize(int corePoolSize){ - executor.setCorePoolSize(corePoolSize); - } - - /** - * 设置线程池最大数量 - * @param maximumPoolSize 最大数量 - */ - @ManagedAttribute - public void setMaximumPoolSize(int maximumPoolSize){ - executor.setMaximumPoolSize(maximumPoolSize); - } - - /** - * 打印填充线程池基本信息 - */ - @ManagedOperation - public void printPoolExecutorInfo() { - log.info("填充线程池corePoolSize:{}、maximumPoolSize:{}.", executor.getCorePoolSize(), executor.getMaximumPoolSize()); - } - /** * 执行异步任务,会等待全部执行完成 * @param tasks 任务集合 @@ -75,11 +36,11 @@ public class DataFillThreadPoolManager { // 主要是为了中转用户信息 List> ttlCallables = tasks.stream().map(TtlCallable::get) .collect(Collectors.toList()); + List> futures = executor.invokeAll(ttlCallables); for (Future future : futures) { future.get(); } } - } diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataGenerate.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataGenerate.java deleted file mode 100644 index 1393257..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataGenerate.java +++ /dev/null @@ -1,42 +0,0 @@ -package fun.easycode.jointblock.datafill; - -import java.lang.annotation.*; - -/** - * 级联查询的时候对于id生成空对象的策略 - * @author xuzhe - */ -@Target({ElementType.FIELD,ElementType.ANNOTATION_TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface DataGenerate { - /** - * 实体的主键名, 默认id - * @return id字段名 - */ - String value(); - - /** - * 目标 - * @return - */ - String targetField(); - - /** - * 如果是多对象模式集合下的的属性类型Class - * @return - */ - Class listClass() default void.class; - - /** - * 多对象模式集合下的主键分隔符默认, - * @return - */ - String listSeparator() default ","; - - /** - * id生成的模式 - * @return - */ - IDGenerateMode mode() default IDGenerateMode.DEFAULT; -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataParam.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataParam.java deleted file mode 100644 index 158eeef..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/DataParam.java +++ /dev/null @@ -1,21 +0,0 @@ -package fun.easycode.jointblock.datafill; - -import java.lang.annotation.*; - -/** - * @author xuzhe - */ -@Retention(RetentionPolicy.RUNTIME) -@Documented -@Target({ElementType.ANNOTATION_TYPE}) -public @interface DataParam { - /** - * 方法的参数名称 - */ - String name(); - - /** - * 方法参数传参值,支持spEl表达式 - */ - String value(); -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/EnableDataFill.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/EnableDataFill.java deleted file mode 100644 index feef901..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/EnableDataFill.java +++ /dev/null @@ -1,13 +0,0 @@ -package fun.easycode.jointblock.datafill; - -import java.lang.annotation.*; - -/** - * 减少不必要的对象扫描 - * @author xuzhe - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@Documented -public @interface EnableDataFill { -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/FeignDataFillStrategy.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/FeignDataFillStrategy.java deleted file mode 100644 index d614cab..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/FeignDataFillStrategy.java +++ /dev/null @@ -1,130 +0,0 @@ -package fun.easycode.jointblock.datafill; - -import cn.hutool.core.util.ReflectUtil; -import fun.easycode.jointblock.exception.CheckException; -import fun.easycode.jointblock.validator.IValidate; -import org.springframework.beans.BeansException; -import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.cloud.openfeign.FeignContext; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.util.StringUtils; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Method; -import java.lang.reflect.Parameter; -import java.util.*; -import java.util.stream.Collectors; - -/** - * feign填充策略 - * - * @author xuzhe - */ -public class FeignDataFillStrategy implements DataFillStrategy, ApplicationContextAware { - - private ApplicationContext context; - - @Override - public void fill(List metadataList) { - - Map, List> sourceMap = metadataList.stream() - .collect(Collectors.groupingBy(metadata -> metadata.getDataFill().source())); - - - sourceMap.forEach((feignClass, feignClassMetadataList) -> { - - FeignClient feignClient = feignClass.getAnnotation(FeignClient.class); - Object clientObj = getFeignBean(feignClient.name(), feignClass); - // 获取DataFill , 只要被处理器处理过传过来的,元数据集合注解的信息是一致的 - DataFill dataFill = metadataList.stream().findFirst().get().getDataFill(); - - Method method; - - if(StringUtils.isEmpty(dataFill.methodName())){ - Method[] methods = ReflectUtil.getMethods(feignClass); - - if (methods.length != 1) { - throw new CheckException(feignClass.getName() + "用于@DataFill时,如果不指定methodName, 则必须有且仅能有一个方法!"); - } - - method = methods[0]; - }else{ - method = ReflectUtil.getMethodByName(feignClass, dataFill.methodName()); - if(method == null){ - throw new CheckException("@DataFill 指定methodName找不到对应的方法!"); - } - } - - // 获取到client请求的主键信息 - List ids = feignClassMetadataList.stream() - .flatMap(metadata -> metadata.getTargetObjMap().keySet().stream()) - .collect(Collectors.toList()); - - // el表达式可以使用的变量 - Map contextProps = new HashMap<>(); - contextProps.put("ids", ids); - - Map> paramMap = Arrays.stream(dataFill.params()) - .collect(Collectors.toMap(DataParam::name - , param -> DataCopy.getInstance() - .parserSpEl(param.value(), Object.class, contextProps))); - - Object invoke; - // 如果标注@DataParam注解,我们将完全按照DataParam标记传参 - // 如果没有注解标记,我们认为方法有且只有一个参数,并传入ids - if (paramMap.size() == 0) { - invoke = ReflectUtil.invoke(clientObj, method, ids); - } else { - // 处理参数列表 - Parameter[] parameters = method.getParameters(); - Object[] args = new Object[parameters.length]; - - // 如果发现feign调用方法的第一个参数实现了IValidate,说明是类传参 - if(IValidate.class.isAssignableFrom(parameters[0].getType())){ - try { - Object cmd = parameters[0].getType().newInstance(); - paramMap.forEach((key, value) -> { - value.ifPresent(o -> ReflectUtil.setFieldValue(cmd, key, o)); - }); - args[0] = cmd; - } catch (Exception e) { - throw new CheckException(parameters[0].getType().getName() + "缺少无参构造!"); - } - }else{ - // 不是非类传参就是直接传参 - for (int i = 0; i < parameters.length; i++) { - Parameter parameter = parameters[i]; - args[i] = paramMap.get(parameter.getName()) == null - ? null : paramMap.get(parameter.getName()).orElse(null); - } - } - // 调用方法 - invoke = ReflectUtil.invoke(clientObj, method, args); - } - - if(invoke != null){ - feignClassMetadataList.forEach(metadata -> { - handlerResult(metadata, invoke, FeignId.class); - }); - } - }); - - } - - @Override - public Class getAnnotation() { - return FeignClient.class; - } - - @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { - this.context = context; - } - - public T getFeignBean(String beanName, Class tClass) { - FeignContext feignContext = context.getBean("feignContext", FeignContext.class); - System.out.println(feignContext.getContextNames()); - return feignContext.getInstance(beanName, tClass); - } -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/FeignId.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/FeignId.java deleted file mode 100644 index 9624286..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/FeignId.java +++ /dev/null @@ -1,13 +0,0 @@ -package fun.easycode.jointblock.datafill; - -import java.lang.annotation.*; - -/** - * 用来标识feign请求返回对象中哪个字段是id - * @author xuzhe - */ -@Target({ElementType.FIELD,ElementType.ANNOTATION_TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface FeignId { -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/IDGenerateMode.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/IDGenerateMode.java deleted file mode 100644 index ba3d44e..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/IDGenerateMode.java +++ /dev/null @@ -1,18 +0,0 @@ -package fun.easycode.jointblock.datafill; - -/** - * 需要填充的id字段要做的处理 - * 因为有些是,分割的所以就需要处理,正常的1对多就没有问题 - * @author xuzhe - */ -public enum IDGenerateMode { - /** - * 默认不做任何处理 - */ - DEFAULT, - /** - * 多个,认为一个字段中有多个Id是用,号分割 - * 排序也会默认根据id的排序进行排序 - */ - MULTIPLE -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/MyBatisPlusDataFillStrategy.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/MyBatisPlusDataFillStrategy.java deleted file mode 100644 index cc031ce..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/datafill/MyBatisPlusDataFillStrategy.java +++ /dev/null @@ -1,90 +0,0 @@ -package fun.easycode.jointblock.datafill; - -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * mybatis-plus填充策略 - * @author xuzhe - */ -public class MyBatisPlusDataFillStrategy implements DataFillStrategy, ApplicationContextAware { - - private ApplicationContext context; - - @SuppressWarnings("all") - @Override - public void fill(List metadataList) { - - Map, List> collect = metadataList.stream() - .collect(Collectors.groupingBy(metadata -> metadata.getDataFill().source())); - - collect.forEach((sourceClass, sourceClassMetadataList) -> { - BaseMapper baseMapper = (BaseMapper) context.getBean(sourceClass); - - List ids = sourceClassMetadataList.stream() - .flatMap(metadata-> metadata.getTargetObjMap().keySet().stream()) - .collect(Collectors.toList()); - - // el表达式可以使用的变量 - Map contextProps = new HashMap<>(); - contextProps.put("ids", ids); - - Map> paramMap = Arrays.stream(sourceClassMetadataList.stream() - .findFirst().get() - .getDataFill().params()) - .collect(Collectors.toMap(DataParam::name - , param -> DataCopy.getInstance() - .parserSpEl(param.value(), Object.class, contextProps))); - - Object invoke; - // 如果标注@DataParam注解,我们将完全按照DataParam标记传参 - // 如果没有注解标记,直接调用BaseMapper的selectBatchIds方法 - if (paramMap.size() == 0) { - invoke = baseMapper.selectBatchIds(ids); - } else { - // 如果传入DataParam列表,将按照参数列表插叙 - // 不要忘记自行塞入 ids, 参考el表达式 - QueryWrapper wrapper = new QueryWrapper<>(); - paramMap.forEach((paramName,paramValue)->{ - if(paramValue.isPresent()){ - // 这里支持Collection参数和单个参数, 用In或者eq - if(paramValue.get() instanceof Collection){ - wrapper.in(paramName, (Collection) paramValue.get()); - }else{ - wrapper.eq(paramName, paramValue.get()); - } - } - }); - invoke = baseMapper.selectList(wrapper); - } - - sourceClassMetadataList.forEach(metadata -> { - // 如果是指定使用自定义注解,我们将使用自定义注解 - if(metadata.getDataFill().isCustomMyBatisPlusAnno()) { - handlerResult(metadata, invoke, DataFillId.class); - }else { - handlerResult(metadata, invoke, TableId.class); - } - }); - }); - } - - @Override - public Class getType() { - return BaseMapper.class; - } - - @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { - this.context = context; - } - - -} -- Gitee From 2a3393bd3ef06665dbe7dc31c4e89a76a3ac8a7f Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Sat, 15 Apr 2023 16:58:20 +0800 Subject: [PATCH 05/22] docs: README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 32aef98..72231ea 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ actuator.addProcess(DataFillProcessBuilder.builder() .fillDataGetFun(lmnIds -> baseDataOrgFeignClient.queryOrgPageList(DataFillProcessBuilder.request(() -> { OrgPageQry qry = new OrgPageQry(); qry.setLmnIdIn(lmnIds.stream().map(String::valueOf).collect(Collectors.toList())); - qry.setPageSize(9999L); + qry.setPageSize((long)lmnIds.size()); return qry; })).getRows()) .fillKeyGetFun(OrgDto::getLmnId) -- Gitee From af11e350d82098ced3ac97a68034024e236699b4 Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Sat, 15 Apr 2023 17:04:21 +0800 Subject: [PATCH 06/22] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=94=9F=E6=88=90=E5=99=A8=E5=AF=B9=E5=AE=A1=E8=AE=A1?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E7=9A=84=E6=94=AF=E6=8C=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelog.md | 4 ++++ .../jointblock/generator/JointBlockGenerator.java | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/changelog.md b/changelog.md index 6f35867..f885da2 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,10 @@ # 0.30.0 feature: - flexible模块增加,特殊情况下动态查询`totalChapter[NotIn]=(6|7|8)` +refactor: +- 重构DataFill,不在使用注解,使用编码的方式增强代码可读性。 +fix: +- 修复代码生成器对审计字段的支持。 # 0.29.0 feature: diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/generator/JointBlockGenerator.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/generator/JointBlockGenerator.java index c9b8edb..9f634d1 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/generator/JointBlockGenerator.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/generator/JointBlockGenerator.java @@ -56,10 +56,10 @@ public final class JointBlockGenerator { .enableRemoveIsPrefix() // 去除boolean类型数据的is_前缀 .enableTableFieldAnnotation() .logicDeleteColumnName("is_deleted") - .addTableFills(new Column("created_by", FieldFill.INSERT) - , new Column("last_modified_by", FieldFill.INSERT_UPDATE) - , new Column("created_date", FieldFill.INSERT) - , new Column("last_modified_date", FieldFill.INSERT_UPDATE)); + .addTableFills(new Column("create_by", FieldFill.INSERT) + , new Column("update_by", FieldFill.INSERT_UPDATE) + , new Column("create_time", FieldFill.INSERT) + , new Column("update_time", FieldFill.INSERT_UPDATE)); // 只有表的前缀有值的时候才进行设置 if(!StringUtils.isEmpty(generatorConfig.getTablePrefix())){ -- Gitee From 735ad79fa67de56b6ce48add9964c7de3796f145 Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Mon, 17 Apr 2023 10:58:44 +0800 Subject: [PATCH 07/22] =?UTF-8?q?refactor:=20flexible=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E7=AE=80=E5=8D=95=E9=87=8D=E6=9E=84=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更改成合理的结构。 --- .../jointblock/flexible/QueryDslParser.java | 32 +++++++++++++++++++ .../QueryHandlerMethodArgumentResolver.java | 26 +++------------ .../jointblock/flexible/QueryParam.java | 6 +--- .../flexible/QueryWrapperBuilder.java | 13 ++++---- 4 files changed, 45 insertions(+), 32 deletions(-) create mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryDslParser.java diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryDslParser.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryDslParser.java new file mode 100644 index 0000000..79d7afe --- /dev/null +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryDslParser.java @@ -0,0 +1,32 @@ +package fun.easycode.jointblock.flexible; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 查询表达式解析器 + * @author xuzhen97 + */ +public class QueryDslParser { + + /** + * 解析查询表达式 + * @param value 查询表达式 + * @param tClass 实体类 + * @param 实体类 + * @return 查询构造器 + */ + public static QueryWrapperBuilder parser(String value, Class tClass) { + QueryWrapperBuilder builder = new QueryWrapperBuilder<>(tClass); + // 整体表达式正则 + Pattern pattern = Pattern.compile("(\\w+?)(\\[.+?\\]=)([a-zA-Z0-9\\\\u4e00-\\\\u9fa5()|]+?),"); + Matcher matcher = pattern.matcher(value + ","); + // 操作符匹配正则 + Pattern operatorPattern = Pattern.compile("(?<=\\[).*(?=\\])"); + while (matcher.find()) { + Matcher operatorMatcher = operatorPattern.matcher( matcher.group(2)); + builder.with(matcher.group(1), operatorMatcher.find() ? operatorMatcher.group() : "", matcher.group(3)); + } + return builder; + } +} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java index 60a6911..bd32d57 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java @@ -1,16 +1,15 @@ package fun.easycode.jointblock.flexible; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import fun.easycode.jointblock.exception.CheckException; import org.springframework.core.MethodParameter; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - +/** + * 查询参数解析器 + * @author xuzhen97 + */ public class QueryHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter methodParameter) { @@ -33,21 +32,6 @@ public class QueryHandlerMethodArgumentResolver implements HandlerMethodArgument return null; } - - return buildQueryWrapper(value, queryParam.root()); - } - - public static QueryWrapper buildQueryWrapper(String value, Class root) { - QueryWrapperBuilder builder = new QueryWrapperBuilder(); - // 整体表达式正则 - Pattern pattern = Pattern.compile("(\\w+?)(\\[.+?\\]=)([a-zA-Z0-9\\\\u4e00-\\\\u9fa5()|]+?),"); - Matcher matcher = pattern.matcher(value + ","); - // 操作符匹配正则 - Pattern operatorPattern = Pattern.compile("(?<=\\[).*(?=\\])"); - while (matcher.find()) { - Matcher operatorMatcher = operatorPattern.matcher( matcher.group(2)); - builder.with(matcher.group(1), operatorMatcher.find() ? operatorMatcher.group() : "", matcher.group(3)); - } - return builder.build(root); + return QueryDslParser.parser(value, queryParam.root()).build(); } } \ No newline at end of file diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryParam.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryParam.java index 152c769..7a05062 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryParam.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryParam.java @@ -2,11 +2,7 @@ package fun.easycode.jointblock.flexible; import org.springframework.core.annotation.AliasFor; -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.lang.annotation.*; @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryWrapperBuilder.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryWrapperBuilder.java index 0d0c8cf..e8f7032 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryWrapperBuilder.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryWrapperBuilder.java @@ -11,24 +11,25 @@ import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class QueryWrapperBuilder { +public class QueryWrapperBuilder { - private List params; + private final List params; + private final Class tClass; - public QueryWrapperBuilder(){ + public QueryWrapperBuilder(Class tClass){ params = new ArrayList<>(); + this.tClass = tClass; } - public QueryWrapperBuilder with(String key, String operation, Object value){ + public QueryWrapperBuilder with(String key, String operation, Object value){ params.add(new SearchCriteria(key, operation, value)); return this; } - public QueryWrapper build(Class tClass){ + public QueryWrapper build(){ if(params.size() == 0){ return null; } - Map columnMap = LambdaUtils.getColumnMap(tClass); QueryWrapper queryWrapper = Wrappers.query(); -- Gitee From 6322336a59ef4b30c034158775c2e04d528246c6 Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Mon, 17 Apr 2023 13:20:38 +0800 Subject: [PATCH 08/22] =?UTF-8?q?refactor:=20flexible=20=E6=AD=A3=E5=88=99?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jointblock/flexible/QueryDslParser.java | 19 +++++++++++++-- .../flexible/QueryWrapperBuilder.java | 23 +++++++++++++++---- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryDslParser.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryDslParser.java index 79d7afe..4f9b9e0 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryDslParser.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryDslParser.java @@ -17,9 +17,14 @@ public class QueryDslParser { * @return 查询构造器 */ public static QueryWrapperBuilder parser(String value, Class tClass) { - QueryWrapperBuilder builder = new QueryWrapperBuilder<>(tClass); + QueryWrapperBuilder builder; + if(tClass == null){ + builder = new QueryWrapperBuilder<>(); + }else{ + builder = new QueryWrapperBuilder<>(tClass); + } // 整体表达式正则 - Pattern pattern = Pattern.compile("(\\w+?)(\\[.+?\\]=)([a-zA-Z0-9\\\\u4e00-\\\\u9fa5()|]+?),"); + Pattern pattern = Pattern.compile("(\\w+?)(\\[.+?\\]=)([a-zA-Z0-9\\u4e00-\\u9fa5()|\\s\\-:]+?),"); Matcher matcher = pattern.matcher(value + ","); // 操作符匹配正则 Pattern operatorPattern = Pattern.compile("(?<=\\[).*(?=\\])"); @@ -29,4 +34,14 @@ public class QueryDslParser { } return builder; } + + /** + * 解析查询表达式 + * @param value 查询表达式 + * @param 实体类 + * @return 查询构造器 + */ + public static QueryWrapperBuilder parser(String value) { + return parser(value, null); + } } diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryWrapperBuilder.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryWrapperBuilder.java index e8f7032..d6d9854 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryWrapperBuilder.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryWrapperBuilder.java @@ -15,10 +15,18 @@ public class QueryWrapperBuilder { private final List params; private final Class tClass; + private final Map columnMap; public QueryWrapperBuilder(Class tClass){ params = new ArrayList<>(); this.tClass = tClass; + columnMap = LambdaUtils.getColumnMap(tClass); + } + + public QueryWrapperBuilder(){ + params = new ArrayList<>(); + this.tClass = null; + this.columnMap = null; } public QueryWrapperBuilder with(String key, String operation, Object value){ @@ -30,20 +38,25 @@ public class QueryWrapperBuilder { if(params.size() == 0){ return null; } - Map columnMap = LambdaUtils.getColumnMap(tClass); - QueryWrapper queryWrapper = Wrappers.query(); for(SearchCriteria criteria : params){ - - String columnKey = LambdaUtils.formatKey(criteria.getKey()); - String tableField = columnMap.get(columnKey).getColumnSelect(); + String tableField = getTableField(criteria.getKey()); // 解析查询条件 analysis(tableField, criteria.getOperation(), criteria.getValue(), queryWrapper); } return queryWrapper; } + private String getTableField(String key){ + if(tClass != null) { + String columnKey = LambdaUtils.formatKey(key); + return columnMap.get(columnKey).getColumnSelect(); + }else{ + return key; + } + } + /** * 解析查询条件 * @param tableField 字段名 -- Gitee From ccc9711787e54c0a3e31156b13ab1a65f452c12d Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Thu, 20 Apr 2023 13:41:29 +0800 Subject: [PATCH 09/22] =?UTF-8?q?refactor:=20=E5=A4=A7=E5=B9=85=E5=BA=A6?= =?UTF-8?q?=E7=B2=BE=E7=AE=80=E6=A1=86=E6=9E=B6=EF=BC=8C=E5=8F=AA=E5=81=9A?= =?UTF-8?q?=E5=BF=85=E8=A6=81=E7=BA=A6=E6=9D=9F=E5=92=8C=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 有太多的功能没有用处。 --- .../JointBlockAutoConfiguration.java | 2 +- .../JointBlockWebAutoConfiguration.java | 14 - .../adpter/api/ArticleRestController.java | 7 +- ...iclePagingQry.java => ArticlePageQry.java} | 4 +- .../service/executor/ArticlePagingQryExe.java | 10 +- ...xeTest.java => ArticlePageQryExeTest.java} | 6 +- .../core/AuditMetaObjectHandler.java | 6 +- .../{mybatisplus => core}/BatchMapper.java | 2 +- .../{exception => core}/CheckException.java | 68 +-- .../jointblock/core/CloudUserHolder.java | 19 - .../easycode/jointblock/core/Condition.java | 14 - .../easycode/jointblock/core/Constant.java | 40 -- .../jointblock/core/DeleteResultConvert.java | 15 - .../jointblock/core/DynamicOperate.java | 425 ++---------------- .../jointblock/core/EnumeratorSerializer.java | 9 +- .../jointblock/core/InsertCallback.java | 16 - .../jointblock/core/InsertResultConvert.java | 15 - .../jointblock/core/JointBlockMapper.java | 11 + .../JointBlockSqlInjector.java | 2 +- .../jointblock/core/LogUpdateWrapper.java | 23 - .../OperateSymbol.java} | 52 ++- .../fun/easycode/jointblock/core/PageDto.java | 71 +-- .../core/{PagingQry.java => PageQry.java} | 2 +- .../{flexible => core}/QueryDslParser.java | 2 +- .../QueryHandlerMethodArgumentResolver.java | 2 +- .../{flexible => core}/QueryParam.java | 2 +- .../QueryWrapperBuilder.java | 27 +- .../ReplaceBatchSomeColumn.java | 2 +- .../{flexible => core}/SearchCriteria.java | 2 +- .../{mybatisplus => core}/StreamMapper.java | 2 +- .../StreamQueryAbstractMethod.java | 2 +- .../StreamQuerySqlAbstractMethod.java | 2 +- .../jointblock/core/UpdateCallback.java | 19 - .../jointblock/core/UpdateResultConvert.java | 15 - .../easycode/jointblock/core/UserHolder.java | 25 +- .../jointblock/flexible/package-info.java | 4 - .../fun/easycode/jointblock/util/LogUtil.java | 119 ----- .../MyBatisPlusSQLLog.java | 2 +- .../{core => util}/RequestHolder.java | 2 +- .../fun/easycode/jointblock/util/URLUtil.java | 1 - .../jointblock/validator/IValidate.java | 3 +- 41 files changed, 161 insertions(+), 905 deletions(-) rename jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/service/dto/{ArticlePagingQry.java => ArticlePageQry.java} (59%) rename jointblock-spring-boot-test/src/test/java/fun/easycode/jointblock/service/executor/{ArticlePagingQryExeTest.java => ArticlePageQryExeTest.java} (90%) rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/{mybatisplus => core}/BatchMapper.java (90%) rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/{exception => core}/CheckException.java (35%) delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/CloudUserHolder.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/Condition.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/Constant.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/DeleteResultConvert.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertCallback.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertResultConvert.java create mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockMapper.java rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/{mybatisplus => core}/JointBlockSqlInjector.java (95%) delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/LogUpdateWrapper.java rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/{flexible/OperationConstant.java => core/OperateSymbol.java} (35%) rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/{PagingQry.java => PageQry.java} (90%) rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/{flexible => core}/QueryDslParser.java (97%) rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/{flexible => core}/QueryHandlerMethodArgumentResolver.java (97%) rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/{flexible => core}/QueryParam.java (91%) rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/{flexible => core}/QueryWrapperBuilder.java (78%) rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/{mybatisplus => core}/ReplaceBatchSomeColumn.java (98%) rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/{flexible => core}/SearchCriteria.java (89%) rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/{mybatisplus => core}/StreamMapper.java (94%) rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/{mybatisplus => core}/StreamQueryAbstractMethod.java (97%) rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/{mybatisplus => core}/StreamQuerySqlAbstractMethod.java (97%) delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/UpdateCallback.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/UpdateResultConvert.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/package-info.java delete mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/LogUtil.java rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/{mybatisplus => util}/MyBatisPlusSQLLog.java (95%) rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/{core => util}/RequestHolder.java (99%) diff --git a/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockAutoConfiguration.java b/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockAutoConfiguration.java index 3ede682..1e3cd65 100644 --- a/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockAutoConfiguration.java +++ b/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockAutoConfiguration.java @@ -8,7 +8,7 @@ import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerIntercep import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import fun.easycode.jointblock.core.AuditMetaObjectHandler; import fun.easycode.jointblock.core.ExecutorContext; -import fun.easycode.jointblock.mybatisplus.JointBlockSqlInjector; +import fun.easycode.jointblock.core.JointBlockSqlInjector; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; diff --git a/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockWebAutoConfiguration.java b/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockWebAutoConfiguration.java index f446034..8c8aae1 100644 --- a/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockWebAutoConfiguration.java +++ b/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockWebAutoConfiguration.java @@ -1,10 +1,7 @@ package fun.easycode.joinblock.autoconfigure; import fun.easycode.jointblock.core.*; -import fun.easycode.jointblock.flexible.QueryHandlerMethodArgumentResolver; import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.context.annotation.Bean; @@ -65,15 +62,4 @@ public class JointBlockWebAutoConfiguration implements WebMvcConfigurer, Jackson jacksonObjectMapperBuilder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer()); jacksonObjectMapperBuilder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer()); } - - /** - * Cloud UserHolder 实例 - * @return UserHolder - */ - @ConditionalOnMissingClass({"org.springframework.security.core.Authentication"}) - @ConditionalOnMissingBean(UserHolder.class) - @Bean - public UserHolder cloudUserHolder(){ - return new CloudUserHolder(); - } } diff --git a/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/adpter/api/ArticleRestController.java b/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/adpter/api/ArticleRestController.java index 8b8a717..869bfaf 100644 --- a/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/adpter/api/ArticleRestController.java +++ b/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/adpter/api/ArticleRestController.java @@ -1,10 +1,9 @@ package fun.easycode.jointblock.adpter.api; import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; -import fun.easycode.jointblock.core.Constant; import fun.easycode.jointblock.core.ExecutorContext; import fun.easycode.jointblock.core.PageDto; -import fun.easycode.jointblock.service.dto.ArticlePagingQry; +import fun.easycode.jointblock.service.dto.ArticlePageQry; import fun.easycode.jointblock.service.dto.data.ArticlePagingDto; import fun.easycode.jointblock.service.executor.ArticlePagingQryExe; import io.swagger.annotations.ApiImplicitParam; @@ -22,10 +21,10 @@ public class ArticleRestController { + "查看别人的能看机审通过、到达发布时间、并且不是草稿、不是驳回的阅读文章") @GetMapping("/articles") @ApiImplicitParams({ - @ApiImplicitParam(name = Constant.CURRENT_USER_ID_HEADER, paramType = "header"), +// @ApiImplicitParam(name = Constant.CURRENT_USER_ID_HEADER, paramType = "header"), @ApiImplicitParam(value = "用户ID", name = "userId") }) - public ResponseEntity> myReadList(ArticlePagingQry qry) { + public ResponseEntity> myReadList(ArticlePageQry qry) { return ResponseEntity.ok(ExecutorContext.get(ArticlePagingQryExe.class).execute(qry)); } } diff --git a/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/service/dto/ArticlePagingQry.java b/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/service/dto/ArticlePageQry.java similarity index 59% rename from jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/service/dto/ArticlePagingQry.java rename to jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/service/dto/ArticlePageQry.java index 8792403..c1cc688 100644 --- a/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/service/dto/ArticlePagingQry.java +++ b/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/service/dto/ArticlePageQry.java @@ -1,11 +1,11 @@ package fun.easycode.jointblock.service.dto; -import fun.easycode.jointblock.core.PagingQry; +import fun.easycode.jointblock.core.PageQry; import fun.easycode.jointblock.validator.IValidate; import lombok.Data; @Data -public class ArticlePagingQry extends PagingQry implements IValidate { +public class ArticlePageQry extends PageQry implements IValidate { // @NotBlank private String userId; } diff --git a/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/service/executor/ArticlePagingQryExe.java b/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/service/executor/ArticlePagingQryExe.java index b040375..89402be 100644 --- a/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/service/executor/ArticlePagingQryExe.java +++ b/jointblock-spring-boot-test/src/main/java/fun/easycode/jointblock/service/executor/ArticlePagingQryExe.java @@ -6,9 +6,8 @@ import fun.easycode.jointblock.core.PageDto; import fun.easycode.jointblock.manager.ArticleClientDto; import fun.easycode.jointblock.manager.ArticleClientQuery; import fun.easycode.jointblock.manager.ArticleServiceClient; -import fun.easycode.jointblock.service.dto.ArticlePagingQry; +import fun.easycode.jointblock.service.dto.ArticlePageQry; import fun.easycode.jointblock.service.dto.data.ArticlePagingDto; -import fun.easycode.jointblock.service.dto.data.ArticlePagingDtoAssembler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; @@ -20,7 +19,7 @@ import java.util.Objects; * @author xuzhe */ @Service -public class ArticlePagingQryExe implements Executor> { +public class ArticlePagingQryExe implements Executor> { private final ArticleServiceClient articleServiceClient; @@ -30,7 +29,7 @@ public class ArticlePagingQryExe implements Executor execute(ArticlePagingQry qry) { + public PageDto execute(ArticlePageQry qry) { qry.validate(); @@ -49,7 +48,8 @@ public class ArticlePagingQryExe implements Executor pageDto = ExecutorContext.get(ArticlePagingQryExe.class).execute(qry); System.out.println(pageDto.getTotalSize()); } diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/AuditMetaObjectHandler.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/AuditMetaObjectHandler.java index c6a462c..29f4d1e 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/AuditMetaObjectHandler.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/AuditMetaObjectHandler.java @@ -24,9 +24,9 @@ public class AuditMetaObjectHandler implements MetaObjectHandler { public void insertFill(MetaObject metaObject) { LocalDateTime now = LocalDateTime.now(); this.strictInsertFill(metaObject, "createTime", ()-> now, LocalDateTime.class); - this.strictInsertFill(metaObject, "createBy", UserHolder.getInstance()::getUserId, String.class); + this.strictInsertFill(metaObject, "createBy",UserHolder.getInstance().getLoginUser()::getId, String.class); this.strictInsertFill(metaObject, "updateTime", ()-> now, LocalDateTime.class); - this.strictInsertFill(metaObject, "updateBy", UserHolder.getInstance()::getUserId, String.class); + this.strictInsertFill(metaObject, "updateBy", UserHolder.getInstance().getLoginUser()::getId, String.class); // 兼容date Date nowDate = new Date(); @@ -38,7 +38,7 @@ public class AuditMetaObjectHandler implements MetaObjectHandler { public void updateFill(MetaObject metaObject) { LocalDateTime now = LocalDateTime.now(); this.strictUpdateFill(metaObject, "updateTime", () -> now, LocalDateTime.class); - this.strictUpdateFill(metaObject, "updateBy", UserHolder.getInstance()::getUserId, String.class); + this.strictUpdateFill(metaObject, "updateBy", UserHolder.getInstance().getLoginUser()::getId, String.class); // 兼容date Date nowDate = new Date(); diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/BatchMapper.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/BatchMapper.java similarity index 90% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/BatchMapper.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/BatchMapper.java index 36eb6f1..9b45469 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/BatchMapper.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/BatchMapper.java @@ -1,4 +1,4 @@ -package fun.easycode.jointblock.mybatisplus; +package fun.easycode.jointblock.core; import java.util.List; diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/exception/CheckException.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/CheckException.java similarity index 35% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/exception/CheckException.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/CheckException.java index 9e4ad40..fe677db 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/exception/CheckException.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/CheckException.java @@ -1,14 +1,11 @@ -package fun.easycode.jointblock.exception; +package fun.easycode.jointblock.core; -import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; -import lombok.Getter; /** * 通用逻辑异常 - * @Author: xuzhen97 - * @Date: 2023/03/22 + * @author xuzhen97 */ @EqualsAndHashCode(callSuper = true) @Data @@ -27,46 +24,53 @@ public class CheckException extends RuntimeException{ * @Date: 2023/03/22 */ private final Integer code; + private final String message; + /** - * 错误信息 - * @Author: xuzhen97 - * @Date: 2023/03/22 + * 通用逻辑异常 + * @param message 错误信息 */ - private final String msg; - - public CheckException(String msg){ - super(msg); + public CheckException(String message){ + super(message); this.code = DEFAULT_CODE; - this.msg = msg; + this.message = message; } - public CheckException(Integer code, String msg){ - super(msg); + /** + * 通用逻辑异常 + * @param code 错误码 + * @param message 错误信息 + */ + public CheckException(Integer code, String message){ + super(message); this.code = code; - this.msg = msg; + this.message = message; } /** - * 返回结果 - * @Author: xuzhen97 - * @Date: 2023/03/22 + * 返回错误信息 + * @return 错误信息 */ - public Result result(){ - return new Result(code, msg); - } - - public static Result toResult(Integer code, String msg){ - return new Result(code, msg); + public ErrorDto error(){ + return new ErrorDto(code, message); } - public static Result toResult(String msg){ - return new Result(DEFAULT_CODE, msg); + /** + * 返回错误信息 + * @param code 错误码 + * @param message 错误信息 + * @return 错误信息 + */ + public static ErrorDto error(Integer code, String message){ + return new ErrorDto(code, message); } - @AllArgsConstructor - @Getter - public static class Result{ - private final Integer code; - private final String msg; + /** + * 返回错误信息 + * @param msg 错误信息 + * @return 错误信息 + */ + public static ErrorDto error(String msg){ + return new ErrorDto(DEFAULT_CODE, msg); } } diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/CloudUserHolder.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/CloudUserHolder.java deleted file mode 100644 index 3e3361b..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/CloudUserHolder.java +++ /dev/null @@ -1,19 +0,0 @@ -package fun.easycode.jointblock.core; - -import fun.easycode.jointblock.exception.CheckException; -import org.springframework.util.StringUtils; - -/** - * 微服务UserHolder实例 - * @author xuzhe - */ -public class CloudUserHolder extends UserHolder{ - @Override - public String getUserId() { - String currUserId = RequestHolder.getRequest().getHeader("x-currUserId"); - if(StringUtils.isEmpty(currUserId)){ - throw new CheckException("x-currUserId header未传入!"); - } - return currUserId; - } -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/Condition.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/Condition.java deleted file mode 100644 index ad50f41..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/Condition.java +++ /dev/null @@ -1,14 +0,0 @@ -package fun.easycode.jointblock.core; - -import java.lang.annotation.*; - -/** - * 条件注解,在修改的时候标识这是条件,不是set - * @author xuzhe - */ -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.FIELD}) -public @interface Condition { - -} \ No newline at end of file diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/Constant.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/Constant.java deleted file mode 100644 index 04b0f87..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/Constant.java +++ /dev/null @@ -1,40 +0,0 @@ -package fun.easycode.jointblock.core; - -/** - * 框架常量 - * @author xuzhe - */ -public interface Constant { - - /** - * 当前页 - */ - int CURRENT = 1; - /** - * 页大小 - */ - int SIZE = 10; - - /** - * 总条数 header key - */ - String TOTAL_SIZE_HEADER = "x-pagination-count"; - - /** - * 总页数 header key - */ - String TOTAL_PAGE_HEADER = "x-pagination-pages"; - /** - * 页大小 header key - */ - String SIZE_HEADER = "x-pagination-size"; - /** - * 当前页 header key - */ - String CURRENT_HEADER = "x-pagination-number"; - - /** - * 当前操作人 header key - */ - String CURRENT_USER_ID_HEADER = "x-currUserId"; -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/DeleteResultConvert.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/DeleteResultConvert.java deleted file mode 100644 index 7b94781..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/DeleteResultConvert.java +++ /dev/null @@ -1,15 +0,0 @@ -package fun.easycode.jointblock.core; - -/** - * 删除返回结果转换 - * @author xuzhe - */ -@FunctionalInterface -public interface DeleteResultConvert { - /** - * 数据库实体T转换为返回结果R - * @param entity 数据库实体 - * @return R - */ - R to(T entity); -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/DynamicOperate.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/DynamicOperate.java index 73c4804..2883b65 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/DynamicOperate.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/DynamicOperate.java @@ -1,21 +1,19 @@ package fun.easycode.jointblock.core; import cn.hutool.core.annotation.AnnotationUtil; -import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ReflectUtil; import com.baomidou.mybatisplus.core.conditions.AbstractWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import fun.easycode.jointblock.exception.CheckException; -import fun.easycode.jointblock.util.LogUtil; import lombok.extern.slf4j.Slf4j; import java.lang.reflect.Field; -import java.time.LocalDateTime; -import java.util.*; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; /** @@ -24,59 +22,6 @@ import java.util.stream.Collectors; */ @Slf4j public final class DynamicOperate { - - /** - * 等于 - */ - public static final String EQ = "Eq"; - /** - * 模糊查询 - */ - public static final String LIKE = "Like"; - /** - * 模糊查询左 - */ - public static final String LIKE_LEFT = "LikeLeft"; - /** - * 模糊查询右 - */ - public static final String LIKE_RIGHT = "LikeRight"; - /** - * 大于 - */ - public static final String GT = "Gt"; - /** - * 小于 - */ - public static final String LT = "Lt"; - /** - * 大于等于 - */ - public static final String GE = "Ge"; - /** - * 小于等于 - */ - public static final String LE = "Le"; - - /** - * in 集合查询 - */ - public static final String IN = "In"; - - /** - * not in 集合查询 - */ - public static final String NOT_IN = "NotIn"; - - /** - * is null 查询 - */ - public static final String IS_NULL = "IsNull"; - - /** - * 排序 - */ - public static final String SORT = "Sort"; /** * 跳过字段, queryWrapper中跳过 */ @@ -110,7 +55,7 @@ public final class DynamicOperate { * @param 查询指令 * @param 转换的返回结果 */ - public static PageDto page(K qry + public static PageDto page(K qry , BaseMapper mapper , QueryResultConvert resultConvert){ QueryWrapper queryWrapper = queryWrapper(qry); @@ -118,230 +63,6 @@ public final class DynamicOperate { return PageDto.toPageDto(page, resultConvert::to); } - /** - * 修改工具方法,注意此方法cmd中的值必须传入,如果未传,数据库会被设置为Null - * @param cmd 修改指令实体 - * @param mapper mybatis mapper - * @param callback 修改回调,用于自定义修改逻辑 - * @param resultConvert 修改实体返回转换 - * @param skipFields 跳过字段,用于那些需要自定义逻辑的字段配合修改回调 - * @return 返回修改后的实体 - * @param 数据库实体 - * @param 修改指令 - * @param 修改后的实体 - */ - public static Optional update(K cmd, BaseMapper mapper - , UpdateCallback callback - , UpdateResultConvert resultConvert - , String... skipFields) { - return update(cmd, mapper, callback, resultConvert, false, false, skipFields); - } - - /** - * 修改工具方法,注意此方法cmd中的值必须传入,如果未传,数据库会被设置为Null - * 此方法进行审计信息的填充update_by、update_time - * 单个对象修改,根据条件必须唯一锁定一条数据 - * - * @param cmd 修改指令实体 - * @param mapper mybatis mapper - * @param callback 修改回调,用于自定义修改逻辑 - * @param resultConvert 修改实体返回转换 - * @param skipFields 跳过字段,用于那些需要自定义逻辑的字段配合修改回调 - * @param 数据库实体 - * @param 修改指令 - * @param 修改后的实体 - * @return 返回修改后的实体 - */ - public static Optional updateNotAudit(K cmd, BaseMapper mapper - , UpdateCallback callback - , UpdateResultConvert resultConvert - , String... skipFields) { - return update(cmd, mapper, callback, resultConvert, false, true, skipFields); - } - - /** - * 修改工具方法 - * - * @param cmd 修改指令实体 - * @param mapper mybatis mapper - * @param callback 修改回调,用于自定义修改逻辑 - * @param resultConvert 修改实体返回转换 - * @param skipEmpty 是否跳过cmd的empty字段,如果要跳过,那么不传入的字段,或者是""这种都不进行修改 - * @param skipAudit 是否跳过审计字段update_by和update_time就不自动传参 - * @param skipFields 跳过字段,用于那些需要自定义逻辑的字段配合修改回调 - * @param 数据库实体 - * @param 修改指令 - * @param 修改后的实体 - * @return 返回修改后的实体 - */ - private static Optional update(K cmd - , BaseMapper mapper - , UpdateCallback callback - , UpdateResultConvert resultConvert - , boolean skipEmpty - , boolean skipAudit - , String... skipFields) { - - Map fieldMap = ReflectUtil.getFieldMap(cmd.getClass()); - List skipFieldList = Arrays.asList(skipFields); - // 生成修改id, 用来记录修改的具体情况,用于打印日志 - String updateId = IdUtil.getSnowflakeNextIdStr(); - UpdateWrapper wrapper = new LogUpdateWrapper<>(updateId); - Queue updateQueue = new LinkedList<>(); - - for (Map.Entry entry : fieldMap.entrySet()) { - // 如果字段要跳过则方法对这个字段不进行任何处理 - if (skipFieldList.stream().anyMatch(skipField -> ObjectUtil.equal(skipField, entry.getKey()))) { - continue; - } - // 在修改的过程中如果被标记条件则称为修改条件 - if (AnnotationUtil.hasAnnotation(entry.getValue(), Condition.class)) { - wrapper(cmd, entry.getKey(), entry.getValue(), wrapper); - } else { - // 如果没有被标记为条件则进行修改 - String fieldName = getDatabaseFieldName(-1, entry.getKey(), entry.getValue()); - Object fieldValue = ReflectUtil.getFieldValue(cmd, entry.getValue()); - if (ObjectUtil.isNotEmpty(fieldValue)) { - updateQueue.offer(fieldName); - updateQueue.offer(fieldValue); - } else if (!skipEmpty) { - // 如果设置跳过empty则为empty的时候不进行修改 - updateQueue.offer(fieldName); - updateQueue.offer(null); - } - } - } - T entity = mapper.selectOne(wrapper); - if (entity != null) { - if (callback != null) { - callback.callback(cmd, wrapper); - } - while (!updateQueue.isEmpty()) { - String updateFieldName = (String) updateQueue.remove(); - Object updateFieldValue = updateQueue.remove(); - wrapper.set(updateFieldName, updateFieldValue); - } - - // 当skipAudit == true, 跳过审计填充 - if (!skipAudit) { - // 审计信息支持 - wrapper.set(camel2under("lastModifiedDate"), LocalDateTime.now()); - wrapper.set(camel2under("lastModifiedBy"), UserHolder.getInstance().getUserId()); - } - mapper.update(null, wrapper); - log.info("update {}: op {} info {}." - , entity.getClass().getSimpleName(), UserHolder.getInstance().getUserId() - , LogUtil.getFieldUpdateLog(updateId, entity)); - if (resultConvert == null) { - return Optional.empty(); - } else { - return Optional.of(resultConvert.to(entity)); - } - } - throw new CheckException("要修改的实体不存在!"); - } - - /** - * 批量修改,自动填充审计lastModifiedDate lastModifiedBy - * 如果值为null会被设置成null - * - * @param cmd - * @param mapper - * @param skipFields - * @param - * @param - */ - public static void updateBatch(K cmd - , BaseMapper mapper - , UpdateCallback callback - , String... skipFields) { - UpdateWrapper updateWrapper = updateWrapper(cmd, false, false, false, skipFields); - updateWrapper = callback.callback(cmd, updateWrapper); - String whereSqlSegment = getWhereSqlSegment(updateWrapper); - String setSql = getSetSqlSegment(updateWrapper); - mapper.update(null, updateWrapper); - log.info("update {} : condition {}, set {}, op {}.", mapper.getClass().getSimpleName() - , whereSqlSegment - , setSql - , UserHolder.getInstance().getUserId()); - } - - /** - * 批量修改,自动填充审计lastModifiedDate lastModifiedBy - * 跳过空值,null不会往数据库设置 - * - * @param cmd - * @param mapper - * @param skipFields - * @param - * @param - */ - public static void updateBatchSkipEmpty(K cmd - , BaseMapper mapper - , UpdateCallback callback - , String... skipFields) { - UpdateWrapper updateWrapper = updateWrapper(cmd, false, false, false, skipFields); - updateWrapper = callback.callback(cmd, updateWrapper); - String whereSqlSegment = getWhereSqlSegment(updateWrapper); - String setSql = getSetSqlSegment(updateWrapper); - mapper.update(null, updateWrapper); - log.info("update {} : condition {}, set {}, op {}.", mapper.getClass().getSimpleName() - , whereSqlSegment - , setSql - , UserHolder.getInstance().getUserId()); - } - - /** - * 批量修改跳过审计,但是不跳过空值,值为null数据库为null - * lastModifiedDate lastModifiedBy - * - * @param cmd - * @param mapper - * @param skipFields - * @param - * @param - */ - public static void updateBatchNotAudit(K cmd - , BaseMapper mapper - , UpdateCallback callback - , String... skipFields) { - UpdateWrapper updateWrapper = updateWrapper(cmd, false, false, true, skipFields); - updateWrapper = callback.callback(cmd, updateWrapper); - String whereSqlSegment = getWhereSqlSegment(updateWrapper); - String setSql = getSetSqlSegment(updateWrapper); - mapper.update(null, updateWrapper); - log.info("update {} : condition {}, set {}, op {}.", mapper.getClass().getSimpleName() - , whereSqlSegment - , setSql - , UserHolder.getInstance().getUserId()); - } - - /** - * 批量修改跳过审计 - * lastModifiedDate lastModifiedBy - * 跳过空值null set - * - * @param cmd - * @param mapper - * @param skipFields - * @param - * @param - */ - public static void updateBatchNotAuditSkipEmpty(K cmd - , BaseMapper mapper - , UpdateCallback callback - , String... skipFields) { - UpdateWrapper updateWrapper = updateWrapper(cmd, false, true, true, skipFields); - updateWrapper = callback.callback(cmd, updateWrapper); - String whereSqlSegment = getWhereSqlSegment(updateWrapper); - String setSql = getSetSqlSegment(updateWrapper); - mapper.update(null, updateWrapper); - log.info("update {} : condition {}, set {}, op {}.", mapper.getClass().getSimpleName() - , whereSqlSegment - , setSql - , UserHolder.getInstance().getUserId()); - } - /** * 根据实体命令生成QueryWrapper条件 * @@ -397,94 +118,6 @@ public final class DynamicOperate { return queryWrapper; } - /** - * 根据指令生成UpdateWrapper - * 如果skipSet=true, 则skipEmpty设置无效 - * - * @param cmd 对象指令 - * @param skipSet 是否跳过set, 跳过set仅仅生成用于查询的wrapper - * @param skipEmpty 是否跳过empty - * , 如果跳过当值为Null或者size=0 以及""这种的时候不进行处理,反之设置为null - * @param skipFields 要跳过的字段,跳过的字段方法就不会处理这种数据 - * @param 实体类型 - * @return UpdateWrapper - */ - public static UpdateWrapper updateWrapper(Object cmd - , boolean skipSet - , boolean skipEmpty - , boolean skipAudit - , String... skipFields) { - - Map fieldMap = ReflectUtil.getFieldMap(cmd.getClass()); - List skipFieldList = Arrays.asList(skipFields); - - UpdateWrapper updateWrapper = new UpdateWrapper<>(); - boolean isCondition = false; - for (Map.Entry entry : fieldMap.entrySet()) { - // 如果字段要跳过则方法对这个字段不进行任何处理 - if (skipFieldList.stream().anyMatch(skipField -> ObjectUtil.equal(skipField, entry.getKey()))) { - continue; - } - // 在修改的过程中如果被标记条件则称为修改条件 - if (AnnotationUtil.hasAnnotation(entry.getValue(), Condition.class)) { - wrapper(cmd, entry.getKey(), entry.getValue(), updateWrapper); - isCondition = true; - } else if (!skipSet) { - // 如果没有被标记为条件则进行修改 - String fieldName = getDatabaseFieldName(-1, entry.getKey(), entry.getValue()); - Object fieldValue = ReflectUtil.getFieldValue(cmd, entry.getValue()); - if (ObjectUtil.isNotEmpty(fieldValue)) { - updateWrapper.set(fieldName, fieldValue); - } else if (!skipEmpty) { - updateWrapper.set(fieldName, null); - } - // 是否跳过审计信息支持 - if (!skipAudit) { - // 审计信息支持 - updateWrapper.set(camel2under("lastModifiedDate"), LocalDateTime.now()); - updateWrapper.set(camel2under("lastModifiedBy"), UserHolder.getInstance().getUserId()); - } - } - } - if (!isCondition) { - throw new CheckException("updateWrapper方法调用必须存在条件@Condition!"); - } - return updateWrapper; - } - - /** - * 获取where sql段用于打印 - * @param wrapper UpdateWrapper - * @return sql - * @param T - */ - private static String getWhereSqlSegment(UpdateWrapper wrapper){ - String sqlSegment = wrapper.getSqlSegment(); - - for(Map.Entry entry : wrapper.getParamNameValuePairs().entrySet()){ - String repKey = "#{ew.paramNameValuePairs."+entry.getKey()+"}"; - sqlSegment = sqlSegment.replace(repKey, String.valueOf(entry.getValue())); - } - return sqlSegment; - } - - /** - * 获取where set sql段用于打印 - * - * @param wrapper UpdateWrapper - * @param T - * @return sql - */ - private static String getSetSqlSegment(UpdateWrapper wrapper) { - String sqlSet = wrapper.getSqlSet(); - - for (Map.Entry entry : wrapper.getParamNameValuePairs().entrySet()) { - String repKey = "#{ew.paramNameValuePairs." + entry.getKey() + "}"; - sqlSet = sqlSet.replace(repKey, String.valueOf(entry.getValue())); - } - return sqlSet; - } - /** * 给wrapper增加条件 * @param o 对象例如qry cmd @@ -494,64 +127,64 @@ public final class DynamicOperate { */ private static void wrapper(Object o, String key, Field field, AbstractWrapper wrapper) { - if (isConditional(key, EQ)) { - int index = lastIndexOf(key, EQ); + if (isConditional(key, OperateSymbol.EQ.getValue())) { + int index = lastIndexOf(key, OperateSymbol.EQ.getValue()); String fieldName = getDatabaseFieldName(index, key, field); Object value = ReflectUtil.getFieldValue(o, field); if (ObjectUtil.isNotEmpty(value)) { wrapper.eq(fieldName, transformValue(value)); } - } else if (isConditional(key, LIKE)) { - int index = lastIndexOf(key, LIKE); + } else if (isConditional(key, OperateSymbol.LIKE.getValue())) { + int index = lastIndexOf(key, OperateSymbol.LIKE.getValue()); String fieldName = getDatabaseFieldName(index, key, field); Object value = ReflectUtil.getFieldValue(o, key); if (ObjectUtil.isNotEmpty(value)) { wrapper.like(fieldName, transformValue(value)); } - } else if (isConditional(key, LIKE_LEFT)) { - int index = lastIndexOf(key, LIKE_LEFT); + } else if (isConditional(key, OperateSymbol.LIKE_LEFT.getValue())) { + int index = lastIndexOf(key, OperateSymbol.LIKE_LEFT.getValue()); String fieldName = getDatabaseFieldName(index, key, field); Object value = ReflectUtil.getFieldValue(o, field); if (ObjectUtil.isNotEmpty(value)) { wrapper.likeLeft(fieldName, transformValue(value)); } - } else if (isConditional(key, LIKE_RIGHT)) { - int index = lastIndexOf(key, LIKE_RIGHT); + } else if (isConditional(key, OperateSymbol.LIKE_RIGHT.getValue())) { + int index = lastIndexOf(key, OperateSymbol.LIKE_RIGHT.getValue()); String fieldName = getDatabaseFieldName(index, key, field); Object value = ReflectUtil.getFieldValue(o, field); if (ObjectUtil.isNotEmpty(value)) { wrapper.likeRight(fieldName, transformValue(value)); } - } else if (isConditional(key, GT)) { - int index = lastIndexOf(key, GT); + } else if (isConditional(key, OperateSymbol.GT.getValue())) { + int index = lastIndexOf(key, OperateSymbol.GT.getValue()); String fieldName = getDatabaseFieldName(index, key, field); Object value = ReflectUtil.getFieldValue(o, field); if (ObjectUtil.isNotEmpty(value)) { wrapper.gt(fieldName, transformValue(value)); } - } else if (isConditional(key, LT)) { - int index = lastIndexOf(key, LT); + } else if (isConditional(key, OperateSymbol.LT.getValue())) { + int index = lastIndexOf(key, OperateSymbol.LT.getValue()); String fieldName = getDatabaseFieldName(index, key, field); Object value = ReflectUtil.getFieldValue(o, field); if (ObjectUtil.isNotEmpty(value)) { wrapper.lt(fieldName, transformValue(value)); } - } else if (isConditional(key, GE)) { - int index = lastIndexOf(key, GE); + } else if (isConditional(key, OperateSymbol.GE.getValue())) { + int index = lastIndexOf(key, OperateSymbol.GE.getValue()); String fieldName = getDatabaseFieldName(index, key, field); Object value = ReflectUtil.getFieldValue(o, field); if (ObjectUtil.isNotEmpty(value)) { wrapper.ge(fieldName, transformValue(value)); } - } else if (isConditional(key, LE)) { - int index = lastIndexOf(key, LE); + } else if (isConditional(key, OperateSymbol.LE.getValue())) { + int index = lastIndexOf(key, OperateSymbol.LE.getValue()); String fieldName = getDatabaseFieldName(index, key, field); Object value = ReflectUtil.getFieldValue(o, field); if (ObjectUtil.isNotEmpty(value)) { wrapper.le(fieldName, transformValue(value)); } - } else if (isConditional(key, IS_NULL)) { - int index = lastIndexOf(key, IS_NULL); + } else if (isConditional(key, OperateSymbol.IS_NULL.getValue())) { + int index = lastIndexOf(key, OperateSymbol.IS_NULL.getValue()); String fieldName = getDatabaseFieldName(index, key, field); Object value = ReflectUtil.getFieldValue(o, field); if (value != null && !(value instanceof Boolean)) { @@ -564,22 +197,22 @@ public final class DynamicOperate { wrapper.isNotNull(fieldName); } } - } else if (isConditional(key, NOT_IN)) { - int index = lastIndexOf(key, NOT_IN); + } else if (isConditional(key, OperateSymbol.NOT_IN.getValue())) { + int index = lastIndexOf(key, OperateSymbol.NOT_IN.getValue()); String fieldName = getDatabaseFieldName(index, key, field); Object value = ReflectUtil.getFieldValue(o, field); if (ObjectUtil.isNotEmpty(value)) { wrapper.notIn(fieldName, (Collection) value); } - } else if (isConditional(key, IN)) { - int index = lastIndexOf(key, IN); + } else if (isConditional(key, OperateSymbol.IN.getValue())) { + int index = lastIndexOf(key, OperateSymbol.IN.getValue()); String fieldName = getDatabaseFieldName(index, key, field); Object value = ReflectUtil.getFieldValue(o, field); if (ObjectUtil.isNotEmpty(value)) { wrapper.in(fieldName, (Collection) value); } - } else if (isConditional(key, SORT)) { - int index = lastIndexOf(key, SORT); + } else if (isConditional(key, OperateSymbol.SORT.getValue())) { + int index = lastIndexOf(key, OperateSymbol.SORT.getValue()); String fieldName = getDatabaseFieldName(index, key, field); Object value = ReflectUtil.getFieldValue(o, field); // 必须传入值,不是DESC其他值均为ASC diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/EnumeratorSerializer.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/EnumeratorSerializer.java index 0efdc5f..8ad159d 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/EnumeratorSerializer.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/EnumeratorSerializer.java @@ -14,9 +14,10 @@ import java.io.IOException; public class EnumeratorSerializer extends JsonSerializer> { @Override public void serialize(Enumerator enumerator, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { - jsonGenerator.writeStartObject(); - jsonGenerator.writeObjectField("value", enumerator.getValue()); - jsonGenerator.writeStringField("desc", enumerator.getDesc()); - jsonGenerator.writeEndObject(); +// jsonGenerator.writeStartObject(); +// jsonGenerator.writeObjectField("value", enumerator.getValue()); +// jsonGenerator.writeStringField("desc", enumerator.getDesc()); +// jsonGenerator.writeEndObject(); + jsonGenerator.writeObject(enumerator.getValue()); } } diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertCallback.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertCallback.java deleted file mode 100644 index b7cb3cb..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertCallback.java +++ /dev/null @@ -1,16 +0,0 @@ -package fun.easycode.jointblock.core; - -/** - * 插入自定义逻辑回调 - * @author xuzhe - */ -@FunctionalInterface -public interface InsertCallback { - /** - * 用户拿指令K和数据库实体T可以进行自己自定义的逻辑 - * @param cmd 指令 - * @param entity 数据库实体 - * @return 数据库实体 - */ - T callback(K cmd, T entity); -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertResultConvert.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertResultConvert.java deleted file mode 100644 index c71fced..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertResultConvert.java +++ /dev/null @@ -1,15 +0,0 @@ -package fun.easycode.jointblock.core; - -/** - * 插入成功返回结果转换 - * @author xuzhe - */ -@FunctionalInterface -public interface InsertResultConvert { - /** - * 数据库实体T转换成自定义返回结果R - * @param entity 数据库实体 - * @return R - */ - R to(T entity); -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockMapper.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockMapper.java new file mode 100644 index 0000000..ff631db --- /dev/null +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockMapper.java @@ -0,0 +1,11 @@ +package fun.easycode.jointblock.core; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * 通用mapper + * 在原版的mapper上增加了批量操作和流式查询 + * @param + */ +public interface JointBlockMapper extends BaseMapper, StreamMapper, BatchMapper{ +} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/JointBlockSqlInjector.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockSqlInjector.java similarity index 95% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/JointBlockSqlInjector.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockSqlInjector.java index fc46482..a0dfd83 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/JointBlockSqlInjector.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockSqlInjector.java @@ -1,4 +1,4 @@ -package fun.easycode.jointblock.mybatisplus; +package fun.easycode.jointblock.core; import com.baomidou.mybatisplus.core.injector.AbstractMethod; import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector; diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/LogUpdateWrapper.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/LogUpdateWrapper.java deleted file mode 100644 index d9e6af5..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/LogUpdateWrapper.java +++ /dev/null @@ -1,23 +0,0 @@ -package fun.easycode.jointblock.core; - -import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; -import fun.easycode.jointblock.util.LogUtil; - -/** - * 扩展UpdateWrapper用于收集插入的字段修改详情 - * @author xuzhe - */ -public class LogUpdateWrapper extends UpdateWrapper { - - private final String updateId; - - public LogUpdateWrapper(String updateId){ - this.updateId = updateId; - } - - @Override - public UpdateWrapper set(String column, Object val) { - LogUtil.setUpdateField(updateId, column, val); - return super.set(column, val); - } -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/OperationConstant.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/OperateSymbol.java similarity index 35% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/OperationConstant.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/OperateSymbol.java index caa5ba5..4c373b4 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/OperationConstant.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/OperateSymbol.java @@ -1,60 +1,74 @@ -package fun.easycode.jointblock.flexible; +package fun.easycode.jointblock.core; /** - * 操作符常量 + * 操作符枚举 * @author xuzhen97 */ -public final class OperationConstant { +public enum OperateSymbol implements Enumerator{ /** * 等于 */ - public static final String EQ = "Eq"; + EQ("Eq", "等于"), /** * 模糊查询 */ - public static final String LIKE = "Like"; + LIKE("Like", "模糊查询"), /** * 模糊查询左 */ - public static final String LIKE_LEFT = "LikeLeft"; + LIKE_LEFT("LikeLeft", "模糊查询左"), /** * 模糊查询右 */ - public static final String LIKE_RIGHT = "LikeRight"; + LIKE_RIGHT("LikeRight", "模糊查询右"), /** * 大于 */ - public static final String GT = "Gt"; + GT("Gt", "大于"), /** * 小于 */ - public static final String LT = "Lt"; + LT("Lt", "小于"), /** * 大于等于 */ - public static final String GE = "Ge"; + GE("Ge", "大于等于"), /** * 小于等于 */ - public static final String LE = "Le"; - + LE("Le", "小于等于"), /** * in 集合查询 */ - public static final String IN = "In"; - + IN("In", "in 集合查询"), /** * not in 集合查询 */ - public static final String NOT_IN = "NotIn"; - + NOT_IN("NotIn", "not in 集合查询"), /** * is null 查询 */ - public static final String IS_NULL = "IsNull"; - + IS_NULL("IsNull", "is null 查询"), /** * 排序 */ - public static final String SORT = "Sort"; + SORT("Sort", "排序"); + private final String value; + private final String desc; + + OperateSymbol(String value, String desc) { + this.value = value; + this.desc = desc; + } + + @Override + public String getValue() { + return value; + } + + @Override + public String getDesc() { + return desc; + } + } diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/PageDto.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/PageDto.java index 0ba210b..8134221 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/PageDto.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/PageDto.java @@ -3,12 +3,8 @@ package fun.easycode.jointblock.core; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.Builder; import lombok.Data; -import org.springframework.http.ResponseEntity; -import java.util.Collection; import java.util.List; -import java.util.Objects; -import java.util.Optional; import java.util.stream.Collectors; /** @@ -32,9 +28,9 @@ public class PageDto { * @param 实体类型 * @return PageDto */ - public static PageDto toPageDto(Page page, Convert convert){ + public static PageDto toPageDto(Page page, QueryResultConvert convert){ - List data = page.getRecords().stream().map(convert::convert) + List data = page.getRecords().stream().map(convert::to) .collect(Collectors.toList()); return PageDto.builder() .current(page.getCurrent()) @@ -45,69 +41,6 @@ public class PageDto { .build(); } - /** - * 根据ResponseEntity 返回值以及qry生成PageDto - * @param qry - * @param entity - * @param convert - * @return - * @param - * @param - * @param - */ - public static > PageDto toPageDto(PagingQry qry, ResponseEntity entity, Convert convert){ - - List data = Objects.requireNonNull(entity.getBody()) - .stream().map(convert::convert).collect(Collectors.toList()); - - return PageDto.builder() - .current(Long.valueOf(qry.getCurrent())) - .totalPage(getHeaderValue(Constant.TOTAL_PAGE_HEADER, entity, 0L, Long.class)) - .totalSize(getHeaderValue(Constant.TOTAL_SIZE_HEADER, entity, 0L, Long.class)) - .size(Long.valueOf(qry.getSize())) - .data(data) - .build(); - } - - /** - * 根据ResponseEntity 返回值生成PageDto - * @param entity - * @param convert - * @return - * @param - * @param - * @param - */ - public static > PageDto toPageDto(ResponseEntity entity, Convert convert){ - - List data = Objects.requireNonNull(entity.getBody()) - .stream().map(convert::convert).collect(Collectors.toList()); - - return PageDto.builder() - .current(getHeaderValue(Constant.CURRENT_HEADER, entity, 1L, Long.class)) - .totalPage(getHeaderValue(Constant.TOTAL_PAGE_HEADER, entity, 0L, Long.class)) - .totalSize(getHeaderValue(Constant.TOTAL_SIZE_HEADER, entity, 0L, Long.class)) - .size(getHeaderValue(Constant.SIZE_HEADER, entity, 10L, Long.class)) - .data(data) - .build(); - } - - /** - * 获取header通用封装方法 - * @param header - * @param responseEntity - * @param defaultValue - * @param type - * @return - * @param - */ - private static T getHeaderValue(String header, ResponseEntity responseEntity, T defaultValue, Class type){ - - return Optional.ofNullable(responseEntity.getHeaders().get(header)) - .map(headers-> cn.hutool.core.convert.Convert.convert(type, headers.get(0))) - .orElse(defaultValue); - } - /** * 转换,这是mybatis plus page类型和dto类型转换的声明 * @param diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/PagingQry.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/PageQry.java similarity index 90% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/PagingQry.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/PageQry.java index 66df9d4..b2865ff 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/PagingQry.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/PageQry.java @@ -9,7 +9,7 @@ import javax.validation.constraints.NotNull; * @author xuzhe */ @Data -public class PagingQry { +public class PageQry { @NotNull private Integer size = 10; @NotNull diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryDslParser.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/QueryDslParser.java similarity index 97% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryDslParser.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/QueryDslParser.java index 4f9b9e0..f288d13 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryDslParser.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/QueryDslParser.java @@ -1,4 +1,4 @@ -package fun.easycode.jointblock.flexible; +package fun.easycode.jointblock.core; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/QueryHandlerMethodArgumentResolver.java similarity index 97% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/QueryHandlerMethodArgumentResolver.java index bd32d57..8d72c75 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryHandlerMethodArgumentResolver.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/QueryHandlerMethodArgumentResolver.java @@ -1,4 +1,4 @@ -package fun.easycode.jointblock.flexible; +package fun.easycode.jointblock.core; import org.springframework.core.MethodParameter; import org.springframework.web.bind.support.WebDataBinderFactory; diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryParam.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/QueryParam.java similarity index 91% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryParam.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/QueryParam.java index 7a05062..fe9c037 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryParam.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/QueryParam.java @@ -1,4 +1,4 @@ -package fun.easycode.jointblock.flexible; +package fun.easycode.jointblock.core; import org.springframework.core.annotation.AliasFor; diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryWrapperBuilder.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/QueryWrapperBuilder.java similarity index 78% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryWrapperBuilder.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/QueryWrapperBuilder.java index d6d9854..8e43ecb 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/QueryWrapperBuilder.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/QueryWrapperBuilder.java @@ -1,11 +1,10 @@ -package fun.easycode.jointblock.flexible; +package fun.easycode.jointblock.core; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.LambdaUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache; -import fun.easycode.jointblock.exception.CheckException; import java.util.*; import java.util.regex.Matcher; @@ -72,33 +71,33 @@ public class QueryWrapperBuilder { return; } - if (Objects.equals(OperationConstant.EQ, operation)) { + if (Objects.equals(OperateSymbol.EQ.getValue(), operation)) { wrapper.eq(tableField, value); - } else if (Objects.equals(OperationConstant.LIKE, operation)) { + } else if (Objects.equals(OperateSymbol.LIKE.getValue(), operation)) { wrapper.like(tableField, value); - } else if (Objects.equals(OperationConstant.LIKE_LEFT, operation)) { + } else if (Objects.equals(OperateSymbol.LIKE_LEFT.getValue(), operation)) { wrapper.likeLeft(tableField, value); - } else if (Objects.equals(OperationConstant.LIKE_RIGHT, operation)) { + } else if (Objects.equals(OperateSymbol.LIKE_RIGHT.getValue(), operation)) { wrapper.likeRight(tableField, value); - } else if (Objects.equals(OperationConstant.GT, operation)) { + } else if (Objects.equals(OperateSymbol.GT.getValue(), operation)) { wrapper.gt(tableField, value); - } else if (Objects.equals(OperationConstant.LT, operation)) { + } else if (Objects.equals(OperateSymbol.LT.getValue(), operation)) { wrapper.lt(tableField, value); - } else if (Objects.equals(OperationConstant.GE, operation)) { + } else if (Objects.equals(OperateSymbol.GE.getValue(), operation)) { wrapper.ge(tableField, value); - } else if (Objects.equals(OperationConstant.LE, operation)) { + } else if (Objects.equals(OperateSymbol.LE.getValue(), operation)) { wrapper.le(tableField, value); - } else if (Objects.equals(OperationConstant.IS_NULL, operation)) { + } else if (Objects.equals(OperateSymbol.IS_NULL.getValue(), operation)) { if ((Boolean) value) { wrapper.isNull(tableField); } else { wrapper.isNotNull(tableField); } - } else if (Objects.equals(OperationConstant.NOT_IN, operation)) { + } else if (Objects.equals(OperateSymbol.NOT_IN.getValue(), operation)) { wrapper.notIn(tableField, getValueCollection(value)); - } else if (Objects.equals(OperationConstant.IN, operation)) { + } else if (Objects.equals(OperateSymbol.IN.getValue(), operation)) { wrapper.in(tableField, getValueCollection(value)); - } else if (Objects.equals(OperationConstant.SORT, operation)) { + } else if (Objects.equals(OperateSymbol.SORT.getValue(), operation)) { if (ObjectUtil.equal(String.valueOf(value).toUpperCase(), "DESC")) { wrapper.orderByDesc(tableField); } else { diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/ReplaceBatchSomeColumn.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/ReplaceBatchSomeColumn.java similarity index 98% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/ReplaceBatchSomeColumn.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/ReplaceBatchSomeColumn.java index 96b19f9..fe1255e 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/ReplaceBatchSomeColumn.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/ReplaceBatchSomeColumn.java @@ -1,4 +1,4 @@ -package fun.easycode.jointblock.mybatisplus; +package fun.easycode.jointblock.core; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.core.injector.AbstractMethod; diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/SearchCriteria.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/SearchCriteria.java similarity index 89% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/SearchCriteria.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/SearchCriteria.java index 3cebb82..12e60dd 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/SearchCriteria.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/SearchCriteria.java @@ -1,4 +1,4 @@ -package fun.easycode.jointblock.flexible; +package fun.easycode.jointblock.core; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/StreamMapper.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamMapper.java similarity index 94% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/StreamMapper.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamMapper.java index 0c5ecc7..204bb41 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/StreamMapper.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamMapper.java @@ -1,4 +1,4 @@ -package fun.easycode.jointblock.mybatisplus; +package fun.easycode.jointblock.core; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.toolkit.Constants; diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/StreamQueryAbstractMethod.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQueryAbstractMethod.java similarity index 97% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/StreamQueryAbstractMethod.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQueryAbstractMethod.java index 367374c..b79c4a0 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/StreamQueryAbstractMethod.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQueryAbstractMethod.java @@ -1,4 +1,4 @@ -package fun.easycode.jointblock.mybatisplus; +package fun.easycode.jointblock.core; import com.baomidou.mybatisplus.core.injector.AbstractMethod; import com.baomidou.mybatisplus.core.metadata.TableInfo; diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/StreamQuerySqlAbstractMethod.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQuerySqlAbstractMethod.java similarity index 97% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/StreamQuerySqlAbstractMethod.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQuerySqlAbstractMethod.java index 5b922c0..0c4eb05 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/StreamQuerySqlAbstractMethod.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQuerySqlAbstractMethod.java @@ -1,4 +1,4 @@ -package fun.easycode.jointblock.mybatisplus; +package fun.easycode.jointblock.core; import com.baomidou.mybatisplus.core.injector.AbstractMethod; import com.baomidou.mybatisplus.core.metadata.TableInfo; diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/UpdateCallback.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/UpdateCallback.java deleted file mode 100644 index 62773e9..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/UpdateCallback.java +++ /dev/null @@ -1,19 +0,0 @@ -package fun.easycode.jointblock.core; - -import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; - -/** - * 修改回调,用于自定义自己的修改逻辑 - * @author xuzhe - */ -@FunctionalInterface -public interface UpdateCallback { - - /** - * 修改自定义逻辑 - * @param cmd 指令 - * @param wrapper UpdateWrapper - * @return UpdateWrapper - */ - UpdateWrapper callback(K cmd, UpdateWrapper wrapper); -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/UpdateResultConvert.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/UpdateResultConvert.java deleted file mode 100644 index 27d2458..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/UpdateResultConvert.java +++ /dev/null @@ -1,15 +0,0 @@ -package fun.easycode.jointblock.core; - -/** - * 修改结果转换 - * @author xuzhe - */ -@FunctionalInterface -public interface UpdateResultConvert { - /** - * 实体T转换成返回结果R - * @param entity 数据库实体 - * @return 要转换的实体 - */ - R to(T entity); -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/UserHolder.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/UserHolder.java index dce2334..5eea298 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/UserHolder.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/UserHolder.java @@ -1,6 +1,5 @@ package fun.easycode.jointblock.core; -import fun.easycode.jointblock.exception.CheckException; import org.jetbrains.annotations.NotNull; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; @@ -23,37 +22,15 @@ public abstract class UserHolder implements ApplicationContextAware { return context.getBean(UserHolder.class); } - /** - * 获取当前用户id - * @return String - */ - public abstract String getUserId(); - /** * 获取当前登录用户 * @return 登录用户 * @param 登录用户泛型 */ - public T getUser(){ + public T getLoginUser(){ throw new CheckException("先重写getUser方法!"); } - /** - * 判断是否登录 - * @return 是否 - */ - public boolean isLogin(){ - throw new CheckException("先重写isLogin方法!"); - } - - /** - * 根据用户名强制下线用户 - * @param username 用户名 - */ - public void offline(String username){ - throw new CheckException("先重写offline方法!"); - } - @Override public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException { diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/package-info.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/package-info.java deleted file mode 100644 index a9b4a26..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/flexible/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 灵活条件设计,特殊场景下用于替代 {@link fun.easycode.jointblock.core.DynamicOperate} - */ -package fun.easycode.jointblock.flexible; \ No newline at end of file diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/LogUtil.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/LogUtil.java deleted file mode 100644 index 257a525..0000000 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/LogUtil.java +++ /dev/null @@ -1,119 +0,0 @@ -package fun.easycode.jointblock.util; - -import cn.hutool.core.annotation.AnnotationUtil; -import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.ReflectUtil; -import fun.easycode.jointblock.core.Alias; -import fun.easycode.jointblock.core.DynamicOperate; -import fun.easycode.jointblock.exception.CheckException; - -import java.lang.reflect.Field; -import java.util.*; -import java.util.Map.Entry; -import java.util.stream.Collectors; - -/** - * entity update log 工具类 - * 用来获取实体的修改日志,哪些字段变更了 - * @author xuzhen97 - */ - -public class LogUtil { - - private static final ThreadLocal> OLD_ENTITY_JSON = ThreadLocal.withInitial(HashMap::new); - private static final ThreadLocal> NEW_ENTITY_JSON = ThreadLocal.withInitial(HashMap::new); - private static final ThreadLocal>> UPDATE_FIELD_QUEUE = ThreadLocal.withInitial(HashMap::new); - - /** - * 设置原先的实体 - * @param key String 唯一id, 实体id - * @param oldEntity 实体 - */ - public static void setOldEntity(String key, Object oldEntity){ - OLD_ENTITY_JSON.get().put(key, JacksonUtil.toJson(oldEntity)); - } - - /** - * 设置修改后的实体 - * @param key String 唯一id, 实体id - * @param oldEntity Object - */ - public static void setNewEntity(String key, Object oldEntity){ - NEW_ENTITY_JSON.get().put(key, JacksonUtil.toJson(oldEntity)); - } - - public static void setUpdateField(String key, String fieldName, Object fieldValue){ - Queue queue = UPDATE_FIELD_QUEUE.get().computeIfAbsent(key, k-> new LinkedList<>()); - queue.offer(fieldName); - queue.offer(fieldValue); - } - - /** - * 获取update log 先调用 - * setOldEntity - * setNewEntity - * 获取后数据会被清除,自行保存字符串 - * @param key String - * @return String - */ - public static String getUpdateLog(String key){ - - String oldJson = OLD_ENTITY_JSON.get().get(key); - String newJson = NEW_ENTITY_JSON.get().get(key); - - OLD_ENTITY_JSON.get().remove(key); - NEW_ENTITY_JSON.get().remove(key); - - return JacksonUtil.diff(oldJson, newJson); - } - - /** - * 获取数据修改日志 - * @param key - * @return - */ - public static String getFieldUpdateLog(String key, T entity){ - Queue queue = UPDATE_FIELD_QUEUE.get().get(key); - - Map entityFieldMap = ReflectUtil - .getFieldMap(entity.getClass()).entrySet().stream().map(entry->{ - // 将field map key转换成小写_ 的形式,如果Alias有值就取 - // 这里其实就是为了转换成数据库filed的形式,为了和mybatis对起来 - String mapKey; - if(AnnotationUtil.hasAnnotation(entry.getValue(), Alias.class)) { - Alias alias = entry.getValue().getAnnotation(Alias.class); - mapKey = alias.value(); - }else{ - mapKey = DynamicOperate.camel2under(entry.getKey()); - } - - return new AbstractMap.SimpleEntry<>(mapKey, entry.getValue()); - }) - .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); - - StringBuilder updateLogBuilder = new StringBuilder(); - - while (!queue.isEmpty()){ - - String updateFieldName = (String) queue.remove(); - Object updateFieldValue = queue.remove(); - - Field entityField = entityFieldMap.get(updateFieldName); - - if(entityField == null){ - throw new CheckException("数据库实体字段不存在!"); - } - - Object entityFieldValue = ReflectUtil.getFieldValue(entity, entityField); - // 只有值真正改变的才会打印日志 - if(ObjectUtil.notEqual(updateFieldValue, entityFieldValue)) { - updateLogBuilder.append("[key=").append(updateFieldName).append(",oldValue=") - .append(entityFieldValue).append(",newValue=").append(updateFieldValue).append("];"); - } - } - UPDATE_FIELD_QUEUE.get().remove(key); - - return updateLogBuilder.toString(); - } - -} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/MyBatisPlusSQLLog.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/MyBatisPlusSQLLog.java similarity index 95% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/MyBatisPlusSQLLog.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/MyBatisPlusSQLLog.java index 1009927..0df7763 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/mybatisplus/MyBatisPlusSQLLog.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/MyBatisPlusSQLLog.java @@ -1,4 +1,4 @@ -package fun.easycode.jointblock.mybatisplus; +package fun.easycode.jointblock.util; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.logging.Log; diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/RequestHolder.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/RequestHolder.java similarity index 99% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/RequestHolder.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/RequestHolder.java index 9f1aaaa..8bc6344 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/RequestHolder.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/RequestHolder.java @@ -1,4 +1,4 @@ -package fun.easycode.jointblock.core; +package fun.easycode.jointblock.util; import lombok.extern.slf4j.Slf4j; import org.springframework.web.context.request.RequestAttributes; diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/URLUtil.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/URLUtil.java index 638baaa..e847bc7 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/URLUtil.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/URLUtil.java @@ -1,6 +1,5 @@ package fun.easycode.jointblock.util; -import fun.easycode.jointblock.core.RequestHolder; import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/validator/IValidate.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/validator/IValidate.java index e38b51e..2fd0b92 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/validator/IValidate.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/validator/IValidate.java @@ -1,7 +1,6 @@ package fun.easycode.jointblock.validator; -import fun.easycode.jointblock.exception.CheckException; -import org.springframework.util.StringUtils; +import fun.easycode.jointblock.core.CheckException; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; -- Gitee From 167be1c95074649a7d5467272d10a58a9d093658 Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Thu, 20 Apr 2023 13:42:53 +0800 Subject: [PATCH 10/22] docs: changelog.md --- changelog.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index f885da2..15407da 100644 --- a/changelog.md +++ b/changelog.md @@ -1,8 +1,9 @@ # 0.30.0 feature: -- flexible模块增加,特殊情况下动态查询`totalChapter[NotIn]=(6|7|8)` +- flexible查询增加,特殊情况下动态查询`totalChapter[NotIn]=(6|7|8)` refactor: - 重构DataFill,不在使用注解,使用编码的方式增强代码可读性。 +- 大幅度精简框架,去除大量无用代码。 fix: - 修复代码生成器对审计字段的支持。 -- Gitee From da4a1e496a9285218cab07099030c95897b0bc34 Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Fri, 21 Apr 2023 17:04:04 +0800 Subject: [PATCH 11/22] refactor: QueryDslParser.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 提取Pattern。 --- .../java/fun/easycode/jointblock/core/QueryDslParser.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/QueryDslParser.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/QueryDslParser.java index f288d13..f4a7436 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/QueryDslParser.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/QueryDslParser.java @@ -9,6 +9,8 @@ import java.util.regex.Pattern; */ public class QueryDslParser { + private static final Pattern QUERY_PATTERN = Pattern.compile("(\\w+?)(\\[.+?\\]=)([a-zA-Z0-9\\u4e00-\\u9fa5()|\\s\\-:]+?),"); + private static final Pattern OPERATOR_PATTERN = Pattern.compile("(?<=\\[).*(?=\\])"); /** * 解析查询表达式 * @param value 查询表达式 @@ -24,12 +26,10 @@ public class QueryDslParser { builder = new QueryWrapperBuilder<>(tClass); } // 整体表达式正则 - Pattern pattern = Pattern.compile("(\\w+?)(\\[.+?\\]=)([a-zA-Z0-9\\u4e00-\\u9fa5()|\\s\\-:]+?),"); - Matcher matcher = pattern.matcher(value + ","); + Matcher matcher = QUERY_PATTERN.matcher(value + ","); // 操作符匹配正则 - Pattern operatorPattern = Pattern.compile("(?<=\\[).*(?=\\])"); while (matcher.find()) { - Matcher operatorMatcher = operatorPattern.matcher( matcher.group(2)); + Matcher operatorMatcher = OPERATOR_PATTERN.matcher( matcher.group(2)); builder.with(matcher.group(1), operatorMatcher.find() ? operatorMatcher.group() : "", matcher.group(3)); } return builder; -- Gitee From f84f110c6385375538d72d82914cec9d3dcfb45d Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Tue, 25 Apr 2023 11:06:19 +0800 Subject: [PATCH 12/22] feature: CamelUnderUtil.java --- .../jointblock/core/DynamicOperate.java | 32 +--------------- .../jointblock/util/CamelUnderUtil.java | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+), 31 deletions(-) create mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/CamelUnderUtil.java diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/DynamicOperate.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/DynamicOperate.java index 2883b65..3e1ff19 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/DynamicOperate.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/DynamicOperate.java @@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.extern.slf4j.Slf4j; +import static fun.easycode.jointblock.util.CamelUnderUtil.*; import java.lang.reflect.Field; import java.util.Arrays; @@ -284,35 +285,4 @@ public final class DynamicOperate { return camel2under(original); } - /** - * 功能:驼峰命名转下划线命名 - * 小写和大写紧挨一起的地方,加上分隔符,然后全部转小写 - */ - public static String camel2under(String c) - { - String separator = "_"; - c = c.replaceAll("([a-z])([A-Z])", "$1"+separator+"$2").toLowerCase(); - return c; - } - - /** - * 功能:下划线命名转驼峰命名 - * 将下划线替换为空格,将字符串根据空格分割成数组,再将每个单词首字母大写 - * @param s - * @return - */ - public static String under2camel(String s) - { - String separator = "_"; - String under=""; - s = s.toLowerCase().replace(separator, " "); - String sarr[]=s.split(" "); - for(int i=0;i Date: Tue, 25 Apr 2023 18:01:49 +0800 Subject: [PATCH 13/22] feature: Either.java --- .../fun/easycode/jointblock/util/Either.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/Either.java diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/Either.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/Either.java new file mode 100644 index 0000000..2e4fd1d --- /dev/null +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/Either.java @@ -0,0 +1,60 @@ +package fun.easycode.jointblock.util; + +import java.util.Optional; +import java.util.function.Function; + +public class Either { + private final E error; + private final R result; + + private Either(E error, R result) { + this.error = error; + this.result = result; + } + + public static Either error(E error) { + return new Either<>(error, null); + } + + public static Either result(R result) { + return new Either<>(null, result); + } + + public Optional getError() { + return Optional.ofNullable(error); + } + + public Optional getResult() { + return Optional.ofNullable(result); + } + + public boolean isError() { + return error != null; + } + + public boolean isResult() { + return result != null; + } + + public Optional mapError(Function mapper) { + if (isError()) { + return Optional.of(mapper.apply(error)); + } + return Optional.empty(); + } + + public Optional mapResult(Function mapper) { + if (isResult()) { + return Optional.of(mapper.apply(result)); + } + return Optional.empty(); + } + + @Override + public String toString() { + if (isError()) { + return "Error: " + error.toString(); + } + return "Result: " + result.toString(); + } +} -- Gitee From 7f489e6bc59b53edee49f1a89168a190b8b8d9bf Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Tue, 25 Apr 2023 22:33:35 +0800 Subject: [PATCH 14/22] =?UTF-8?q?feature:=20MyBaitsPlus=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0InsertOrUpdateBathMethod=E6=96=B9=E6=B3=95=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit insert into table (id,name) values (1,'xuzhen'),(2,'xuzhen2') ON DUPLICATE KEY UPDATE name=VALUES(name) --- .../core/InsertOrUpdateBathMethod.java | 78 +++++++++++++++++++ .../jointblock/core/JointBlockMapper.java | 11 +++ .../core/JointBlockSqlInjector.java | 1 + 3 files changed, 90 insertions(+) create mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertOrUpdateBathMethod.java diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertOrUpdateBathMethod.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertOrUpdateBathMethod.java new file mode 100644 index 0000000..39d297f --- /dev/null +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertOrUpdateBathMethod.java @@ -0,0 +1,78 @@ +package fun.easycode.jointblock.core; + +import com.baomidou.mybatisplus.core.injector.AbstractMethod; +import com.baomidou.mybatisplus.core.metadata.TableInfo; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import org.apache.ibatis.executor.keygen.NoKeyGenerator; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.SqlSource; + +/** + * 批量插入或更新 + * insert into table (id,name) values (1,'xuzhen'),(2,'xuzhen2') ON DUPLICATE KEY UPDATE name=VALUES(name) + * @author xuzhen97 + */ +public class InsertOrUpdateBathMethod extends AbstractMethod { + @Override + public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { + final String sql = ""; + final String tableName = tableInfo.getTableName(); + final String filedSql = prepareFieldSql(tableInfo); + final String modelValuesSql = prepareModelValuesSql(tableInfo); + final String duplicateKeySql =prepareDuplicateKeySql(tableInfo); + final String sqlResult = String.format(sql, tableName, filedSql, modelValuesSql,duplicateKeySql); + //System.out.println("savaorupdatesqlsql="+sqlResult); + SqlSource sqlSource = languageDriver.createSqlSource(configuration, sqlResult, modelClass); + return this.addInsertMappedStatement(mapperClass, modelClass, "insertOrUpdateBath", sqlSource, new NoKeyGenerator(), null, null); + } + + /** + * 准备ON DUPLICATE KEY UPDATE sql + * @param tableInfo + * @return + */ + private String prepareDuplicateKeySql(TableInfo tableInfo) { + final StringBuilder duplicateKeySql = new StringBuilder(); + if(!StringUtils.isEmpty(tableInfo.getKeyColumn())) { + duplicateKeySql.append(tableInfo.getKeyColumn()).append("=values(").append(tableInfo.getKeyColumn()).append("),"); + } + + tableInfo.getFieldList().forEach(x -> { + duplicateKeySql.append(x.getColumn()) + .append("=values(") + .append(x.getColumn()) + .append("),"); + }); + duplicateKeySql.delete(duplicateKeySql.length() - 1, duplicateKeySql.length()); + return duplicateKeySql.toString(); + } + + /** + * 准备属性名 + * @param tableInfo + * @return + */ + private String prepareFieldSql(TableInfo tableInfo) { + StringBuilder fieldSql = new StringBuilder(); + fieldSql.append(tableInfo.getKeyColumn()).append(","); + tableInfo.getFieldList().forEach(x -> { + fieldSql.append(x.getColumn()).append(","); + }); + fieldSql.delete(fieldSql.length() - 1, fieldSql.length()); + fieldSql.insert(0, "("); + fieldSql.append(")"); + return fieldSql.toString(); + } + + private String prepareModelValuesSql(TableInfo tableInfo){ + final StringBuilder valueSql = new StringBuilder(); + valueSql.append(""); + if(!StringUtils.isEmpty(tableInfo.getKeyProperty())) { + valueSql.append("#{item.").append(tableInfo.getKeyProperty()).append("},"); + } + tableInfo.getFieldList().forEach(x -> valueSql.append("#{item.").append(x.getProperty()).append("},")); + valueSql.delete(valueSql.length() - 1, valueSql.length()); + valueSql.append(""); + return valueSql.toString(); + } +} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockMapper.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockMapper.java index ff631db..ecd0dcf 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockMapper.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockMapper.java @@ -1,6 +1,9 @@ package fun.easycode.jointblock.core; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; /** * 通用mapper @@ -8,4 +11,12 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; * @param */ public interface JointBlockMapper extends BaseMapper, StreamMapper, BatchMapper{ + + /** + * 批量插入或更新 + * insert into table (id, name) values (1, 'a'), (2, 'b') on duplicate key update name = values(name) + * @param list 数据集 + * @return 影响行数 + */ + int insertOrUpdateBath(@Param("list") List list); } diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockSqlInjector.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockSqlInjector.java index a0dfd83..64d12cb 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockSqlInjector.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockSqlInjector.java @@ -19,6 +19,7 @@ public class JointBlockSqlInjector extends DefaultSqlInjector { methodList.add(new ReplaceBatchSomeColumn()); methodList.add(new StreamQuerySqlAbstractMethod()); methodList.add(new StreamQueryAbstractMethod()); + methodList.add(new InsertOrUpdateBathMethod()); return methodList; } } -- Gitee From fac7a002f0de5d2261d175690877c80b2dd7e2fe Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Tue, 2 May 2023 20:04:57 +0800 Subject: [PATCH 15/22] =?UTF-8?q?feature:=20spring-boot-configuration-proc?= =?UTF-8?q?essor=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 注解处理器。 --- jointblock-spring-boot-parent/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/jointblock-spring-boot-parent/pom.xml b/jointblock-spring-boot-parent/pom.xml index f710524..06e8d02 100644 --- a/jointblock-spring-boot-parent/pom.xml +++ b/jointblock-spring-boot-parent/pom.xml @@ -137,6 +137,11 @@ lombok-mapstruct-binding 0.2.0 + + org.springframework.boot + spring-boot-configuration-processor + ${spring-boot.version} + -- Gitee From f733c15805d959adf801a364e65ed306dde0c977 Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Thu, 4 May 2023 22:35:03 +0800 Subject: [PATCH 16/22] =?UTF-8?q?feature:=20=E9=BB=98=E8=AE=A4=E7=9A=84Use?= =?UTF-8?q?rHolder=E9=85=8D=E7=BD=AE=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JointBlockAutoConfiguration.java | 21 ++++++++++--------- .../easycode/jointblock/core/UserHolder.java | 16 ++++++++++---- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockAutoConfiguration.java b/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockAutoConfiguration.java index 1e3cd65..32c41f7 100644 --- a/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockAutoConfiguration.java +++ b/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockAutoConfiguration.java @@ -9,10 +9,8 @@ import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerIntercept import fun.easycode.jointblock.core.AuditMetaObjectHandler; import fun.easycode.jointblock.core.ExecutorContext; import fun.easycode.jointblock.core.JointBlockSqlInjector; +import fun.easycode.jointblock.core.UserHolder; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -26,9 +24,17 @@ import org.springframework.context.annotation.Configuration; @EnableConfigurationProperties(JointBlockProperties.class) @Configuration @Slf4j -public class JointBlockAutoConfiguration implements BeanFactoryAware{ +public class JointBlockAutoConfiguration { - private BeanFactory beanFactory; + /** + * 配置用户信息获取器,如果用户自己配置则默认配置失效 + * @return UserHolder + */ + @Bean + @ConditionalOnMissingBean(UserHolder.class) + public UserHolder userHolder(){ + return new UserHolder.DefaultUserHolder(); + } /** * 配置mybatis plus插件, 如果用户自己配置则默认配置失效 @@ -77,9 +83,4 @@ public class JointBlockAutoConfiguration implements BeanFactoryAware{ public ExecutorContext executorContext(){ return new ExecutorContext(); } - - @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - this.beanFactory = beanFactory; - } } diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/UserHolder.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/UserHolder.java index 5eea298..15446ba 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/UserHolder.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/UserHolder.java @@ -10,7 +10,7 @@ import org.springframework.context.ApplicationContextAware; * 用户持有者,用来操作当前用户信息 * @author xuzhe */ -public abstract class UserHolder implements ApplicationContextAware { +public abstract class UserHolder implements ApplicationContextAware { private static ApplicationContext context; @@ -25,13 +25,11 @@ public abstract class UserHolder implements ApplicationContextAware { /** * 获取当前登录用户 * @return 登录用户 - * @param 登录用户泛型 */ - public T getLoginUser(){ + public T getLoginUser(){ throw new CheckException("先重写getUser方法!"); } - @Override public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException { context = applicationContext; @@ -44,4 +42,14 @@ public abstract class UserHolder implements ApplicationContextAware { protected static ApplicationContext getContext(){ return context; } + + /** + * 默认的UserHolder + */ + public static class DefaultUserHolder extends UserHolder{ + @Override + public UserInfo getLoginUser() { + return () -> "jointblock"; + } + } } -- Gitee From 9f1be05f2e2d30ca8e9572501f47f6d371a24a8f Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Fri, 5 May 2023 15:44:41 +0800 Subject: [PATCH 17/22] refactor: remove err println. --- .../easycode/jointblock/core/StreamQuerySqlAbstractMethod.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQuerySqlAbstractMethod.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQuerySqlAbstractMethod.java index 0c4eb05..3237230 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQuerySqlAbstractMethod.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQuerySqlAbstractMethod.java @@ -10,8 +10,6 @@ public class StreamQuerySqlAbstractMethod extends AbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { String sqlFormat = ""; - System.err.println(tableInfo.getAllSqlSelect()); - String sql = String.format(sqlFormat, tableInfo.getAllSqlSelect(), tableInfo.getTableName(), "${customSql}"); -- Gitee From 248ca1a46b34a85e3b321fd5fa6ddaa99d52e063 Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Fri, 5 May 2023 16:50:12 +0800 Subject: [PATCH 18/22] =?UTF-8?q?fix:=20stream=20query=E4=BD=BF=E7=94=A8my?= =?UTF-8?q?batis=20plus=E7=9A=84=E6=B3=A8=E8=A7=A3=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fun/easycode/jointblock/core/StreamQueryAbstractMethod.java | 2 +- .../easycode/jointblock/core/StreamQuerySqlAbstractMethod.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQueryAbstractMethod.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQueryAbstractMethod.java index b79c4a0..b5c96a4 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQueryAbstractMethod.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQueryAbstractMethod.java @@ -20,7 +20,7 @@ public class StreamQueryAbstractMethod extends AbstractMethod { } /* 缓存逻辑处理 */ return builderAssistant.addMappedStatement(METHOD, sqlSource, StatementType.PREPARED, SqlCommandType.SELECT, - Integer.MIN_VALUE, null, null, null, null, modelClass, + Integer.MIN_VALUE, null, null, null, tableInfo.getResultMap(), modelClass, ResultSetType.FORWARD_ONLY, true, true, false, null, null, null, configuration.getDatabaseId(), languageDriver, null); } diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQuerySqlAbstractMethod.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQuerySqlAbstractMethod.java index 3237230..d6d6baf 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQuerySqlAbstractMethod.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/StreamQuerySqlAbstractMethod.java @@ -21,7 +21,7 @@ public class StreamQuerySqlAbstractMethod extends AbstractMethod { } /* 缓存逻辑处理 */ return builderAssistant.addMappedStatement(METHOD, sqlSource, StatementType.PREPARED, SqlCommandType.SELECT, - Integer.MIN_VALUE, null, null, null, null, modelClass, + Integer.MIN_VALUE, null, null, null, tableInfo.getResultMap() , modelClass, ResultSetType.FORWARD_ONLY, true, true, false, null, null, null, configuration.getDatabaseId(), languageDriver, null); } -- Gitee From 1f62f03a2ed870e6c36477d9eecf22c5d21cd65a Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Fri, 5 May 2023 21:53:30 +0800 Subject: [PATCH 19/22] =?UTF-8?q?refactor:=20insertOrUpdateBatch=20?= =?UTF-8?q?=E6=9B=B4=E5=90=8D=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...OrUpdateBathMethod.java => InsertOrUpdateBatchMethod.java} | 4 ++-- .../java/fun/easycode/jointblock/core/JointBlockMapper.java | 2 +- .../fun/easycode/jointblock/core/JointBlockSqlInjector.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/{InsertOrUpdateBathMethod.java => InsertOrUpdateBatchMethod.java} (96%) diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertOrUpdateBathMethod.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertOrUpdateBatchMethod.java similarity index 96% rename from jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertOrUpdateBathMethod.java rename to jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertOrUpdateBatchMethod.java index 39d297f..5daafb1 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertOrUpdateBathMethod.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/InsertOrUpdateBatchMethod.java @@ -12,7 +12,7 @@ import org.apache.ibatis.mapping.SqlSource; * insert into table (id,name) values (1,'xuzhen'),(2,'xuzhen2') ON DUPLICATE KEY UPDATE name=VALUES(name) * @author xuzhen97 */ -public class InsertOrUpdateBathMethod extends AbstractMethod { +public class InsertOrUpdateBatchMethod extends AbstractMethod { @Override public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { final String sql = ""; @@ -23,7 +23,7 @@ public class InsertOrUpdateBathMethod extends AbstractMethod { final String sqlResult = String.format(sql, tableName, filedSql, modelValuesSql,duplicateKeySql); //System.out.println("savaorupdatesqlsql="+sqlResult); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sqlResult, modelClass); - return this.addInsertMappedStatement(mapperClass, modelClass, "insertOrUpdateBath", sqlSource, new NoKeyGenerator(), null, null); + return this.addInsertMappedStatement(mapperClass, modelClass, "insertOrUpdateBatch", sqlSource, new NoKeyGenerator(), null, null); } /** diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockMapper.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockMapper.java index ecd0dcf..614d49d 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockMapper.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockMapper.java @@ -18,5 +18,5 @@ public interface JointBlockMapper extends BaseMapper, StreamMapper, Bat * @param list 数据集 * @return 影响行数 */ - int insertOrUpdateBath(@Param("list") List list); + int insertOrUpdateBatch(@Param("list") List list); } diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockSqlInjector.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockSqlInjector.java index 64d12cb..2dee3c5 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockSqlInjector.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/core/JointBlockSqlInjector.java @@ -19,7 +19,7 @@ public class JointBlockSqlInjector extends DefaultSqlInjector { methodList.add(new ReplaceBatchSomeColumn()); methodList.add(new StreamQuerySqlAbstractMethod()); methodList.add(new StreamQueryAbstractMethod()); - methodList.add(new InsertOrUpdateBathMethod()); + methodList.add(new InsertOrUpdateBatchMethod()); return methodList; } } -- Gitee From b01f291a78c8a1a654b993e353bf8d18528fc079 Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Thu, 11 May 2023 11:17:07 +0800 Subject: [PATCH 20/22] =?UTF-8?q?feature:=20=E5=A2=9E=E5=8A=A0=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E7=B1=BB=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BatchUtil.java 批处理工具类。 ExceptionUtil.java 异常信息获取工具类。 --- .../JointBlockAutoConfiguration.java | 9 +++ .../easycode/jointblock/util/BatchUtil.java | 63 +++++++++++++++++++ .../fun/easycode/jointblock/util/Either.java | 23 ++++++- .../jointblock/util/ExceptionUtil.java | 13 ++++ 4 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/BatchUtil.java create mode 100644 jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/ExceptionUtil.java diff --git a/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockAutoConfiguration.java b/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockAutoConfiguration.java index 32c41f7..32bab01 100644 --- a/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockAutoConfiguration.java +++ b/jointblock-spring-boot-autoconfigure/src/main/java/fun/easycode/joinblock/autoconfigure/JointBlockAutoConfiguration.java @@ -10,7 +10,10 @@ import fun.easycode.jointblock.core.AuditMetaObjectHandler; import fun.easycode.jointblock.core.ExecutorContext; import fun.easycode.jointblock.core.JointBlockSqlInjector; import fun.easycode.jointblock.core.UserHolder; +import fun.easycode.jointblock.util.BatchUtil; import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.session.SqlSessionFactory; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -26,6 +29,12 @@ import org.springframework.context.annotation.Configuration; @Slf4j public class JointBlockAutoConfiguration { + @Bean + @ConditionalOnBean(SqlSessionFactory.class) + public BatchUtil batchUtil(SqlSessionFactory factory){ + return new BatchUtil(factory); + } + /** * 配置用户信息获取器,如果用户自己配置则默认配置失效 * @return UserHolder diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/BatchUtil.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/BatchUtil.java new file mode 100644 index 0000000..30e6682 --- /dev/null +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/BatchUtil.java @@ -0,0 +1,63 @@ +package fun.easycode.jointblock.util; + +import fun.easycode.jointblock.core.JointBlockMapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.session.ExecutorType; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; + +import java.util.List; + +/** + * 批处理工具类 + * 必须被spring管理才可以使用 + * @author xuzhen97 + */ +@Slf4j +public class BatchUtil { + /** + * 批处理数量 + */ + private static final int BATCH = 1000; + + /** + * MyBatis SqlSessionFactory + */ + private static SqlSessionFactory SQL_SESSION_FACTORY; + + public BatchUtil(SqlSessionFactory sqlSessionFactory) { + SQL_SESSION_FACTORY = sqlSessionFactory; + } + + /** + * 批量插入方法 + * + * @param data 需要被处理的数据 + * @param mapper 实体类的mapper + * @return int 影响的总行数 + */ + public static int saveBatch(List data, JointBlockMapper mapper) { + + if(SQL_SESSION_FACTORY == null){ + throw new RuntimeException("SQL_SESSION_FACTORY is null, 请先使用spring管理BatchUtil"); + } + + int count = 0; + SqlSession batchSqlSession = SQL_SESSION_FACTORY.openSession(ExecutorType.BATCH); + try { + for (int index = 0; index < data.size(); index++) { + count += mapper.insert(data.get(index)); + if (index != 0 && index % BATCH == 0) { + batchSqlSession.flushStatements(); + } + } + batchSqlSession.commit(); + } catch (Exception e) { + batchSqlSession.rollback(); + log.error(e.getMessage(), e); + } finally { + batchSqlSession.close(); + } + return count; + } +} diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/Either.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/Either.java index 2e4fd1d..0afa9da 100644 --- a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/Either.java +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/Either.java @@ -3,7 +3,7 @@ package fun.easycode.jointblock.util; import java.util.Optional; import java.util.function.Function; -public class Either { +public class Either { private final E error; private final R result; @@ -12,11 +12,11 @@ public class Either { this.result = result; } - public static Either error(E error) { + public static Either error(E error) { return new Either<>(error, null); } - public static Either result(R result) { + public static Either result(R result) { return new Either<>(null, result); } @@ -57,4 +57,21 @@ public class Either { } return "Result: " + result.toString(); } + + /** + * 将一个可能抛出异常的方法转换为Either + * @param function 可能抛出异常的方法 + * @return Either + * @param 参数类型 + * @param 返回值类型 + */ + public static Function> wrap(Function function){ + return t -> { + try { + return Either.result(function.apply(t)); + } catch (Exception e) { + return Either.error(e); + } + }; + } } diff --git a/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/ExceptionUtil.java b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/ExceptionUtil.java new file mode 100644 index 0000000..27f5bce --- /dev/null +++ b/jointblock-spring-boot/src/main/java/fun/easycode/jointblock/util/ExceptionUtil.java @@ -0,0 +1,13 @@ +package fun.easycode.jointblock.util; + +import java.io.PrintWriter; +import java.io.StringWriter; + +public class ExceptionUtil { + public static String getStackTrace(Throwable throwable) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw, true); + throwable.printStackTrace(pw); + return sw.getBuffer().toString(); + } +} -- Gitee From 52deab59b2997d3e39bfad4e3d4937529e42aa6d Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Fri, 12 May 2023 10:50:40 +0800 Subject: [PATCH 21/22] =?UTF-8?q?feature:=20=E5=A2=9E=E5=8A=A0=E7=88=B6?= =?UTF-8?q?=E7=BA=A7=E4=BE=9D=E8=B5=96=E7=AE=A1=E7=90=86=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jointblock-spring-boot-parent/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/jointblock-spring-boot-parent/pom.xml b/jointblock-spring-boot-parent/pom.xml index 06e8d02..9c4956e 100644 --- a/jointblock-spring-boot-parent/pom.xml +++ b/jointblock-spring-boot-parent/pom.xml @@ -64,6 +64,11 @@ mybatis-plus-boot-starter ${mybatis-plus.version} + + com.baomidou + mybatis-plus + ${mybatis-plus.version} + com.baomidou mybatis-plus-generator -- Gitee From aab6c08f106048410e9cad2d63c3dff5c09e06c0 Mon Sep 17 00:00:00 2001 From: xuzhen97 Date: Fri, 12 May 2023 10:51:43 +0800 Subject: [PATCH 22/22] =?UTF-8?q?feature:=20=E5=A2=9E=E5=8A=A0=E7=88=B6?= =?UTF-8?q?=E7=BA=A7=E4=BE=9D=E8=B5=96=E7=AE=A1=E7=90=86=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jointblock-spring-boot-parent/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/jointblock-spring-boot-parent/pom.xml b/jointblock-spring-boot-parent/pom.xml index 9c4956e..c22bfec 100644 --- a/jointblock-spring-boot-parent/pom.xml +++ b/jointblock-spring-boot-parent/pom.xml @@ -79,6 +79,11 @@ jointblock-spring-boot-starter ${jointblock.version} + + fun.easycode + jointblock-spring-boot + ${jointblock.version} + com.github.xiaoymin knife4j-spring-boot-starter -- Gitee