diff --git a/choerodon-gitlab4j-api/pom.xml b/choerodon-gitlab4j-api/pom.xml
index 3b42a939..16a7aa42 100644
--- a/choerodon-gitlab4j-api/pom.xml
+++ b/choerodon-gitlab4j-api/pom.xml
@@ -4,7 +4,7 @@
4.0.0
choerodon-gitlab4j-api
- 2.0.0.RELEASE
+ 2.2.0-19-SNAPSHOT
jar
choerodon-gitlab4j-api
GitLab API Java Client
@@ -21,7 +21,7 @@
io.choerodon
choerodon-starter-parent
- 2.0.0.RELEASE
+ 2.2.0-19-SNAPSHOT
package
diff --git a/choerodon-gitlab4j-api/src/main/java/org/gitlab4j/api/RepositoryApi.java b/choerodon-gitlab4j-api/src/main/java/org/gitlab4j/api/RepositoryApi.java
index 5dcb8c2d..61e1e96e 100644
--- a/choerodon-gitlab4j-api/src/main/java/org/gitlab4j/api/RepositoryApi.java
+++ b/choerodon-gitlab4j-api/src/main/java/org/gitlab4j/api/RepositoryApi.java
@@ -464,7 +464,7 @@ public InputStream getRawBlobContent(Integer projectId, String sha) throws GitLa
*/
public InputStream getRepositoryArchive(Integer projectId, String sha) throws GitLabApiException {
Form formData = new GitLabApiForm().withParam("sha", sha);
- Response response = getWithAccepts(Response.Status.OK, formData.asMap(), MediaType.MEDIA_TYPE_WILDCARD,
+ Response response = getWithAccepts(Response.Status.OK, formData.asMap(), MediaType.WILDCARD,
"projects", projectId, "repository", "archive");
return (response.readEntity(InputStream.class));
}
diff --git a/choerodon-starter-asgard/pom.xml b/choerodon-starter-asgard/pom.xml
index 1d79864f..a6e4e385 100644
--- a/choerodon-starter-asgard/pom.xml
+++ b/choerodon-starter-asgard/pom.xml
@@ -5,12 +5,11 @@
choerodon-starter-parent
io.choerodon
- 2.0.0.RELEASE
+ 2.2.0-19-SNAPSHOT
4.0.0
choerodon-starter-asgard
- 2.0.0.RELEASE
@@ -50,4 +49,4 @@
-
\ No newline at end of file
+
diff --git a/choerodon-starter-asgard/src/main/java/io/choerodon/asgard/schedule/ScheduleConsumer.java b/choerodon-starter-asgard/src/main/java/io/choerodon/asgard/schedule/ScheduleConsumer.java
index 556540de..302fa5a9 100644
--- a/choerodon-starter-asgard/src/main/java/io/choerodon/asgard/schedule/ScheduleConsumer.java
+++ b/choerodon-starter-asgard/src/main/java/io/choerodon/asgard/schedule/ScheduleConsumer.java
@@ -1,21 +1,7 @@
package io.choerodon.asgard.schedule;
-import com.fasterxml.jackson.core.type.TypeReference;
-
-import io.choerodon.asgard.common.AbstractAsgardConsumer;
-import io.choerodon.asgard.common.ApplicationContextHelper;
-import io.choerodon.asgard.common.UpdateStatusDTO;
-import io.choerodon.asgard.schedule.annotation.JobTask;
-import io.choerodon.asgard.schedule.dto.PollScheduleInstanceDTO;
-import io.choerodon.asgard.schedule.dto.ScheduleInstanceConsumerDTO;
-import io.choerodon.asgard.schedule.feign.ScheduleConsumerClient;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.TransactionStatus;
-import org.springframework.util.StringUtils;
+import static io.choerodon.asgard.common.InstanceResultUtils.*;
import java.io.IOException;
import java.util.HashMap;
@@ -26,9 +12,20 @@
import java.util.concurrent.ScheduledExecutorService;
import java.util.stream.Collectors;
-import static io.choerodon.asgard.common.InstanceResultUtils.getErrorInfoFromException;
-import static io.choerodon.asgard.common.InstanceResultUtils.getLoggerException;
-import static io.choerodon.asgard.common.InstanceResultUtils.resultToJson;
+import com.fasterxml.jackson.core.type.TypeReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionStatus;
+import org.springframework.util.StringUtils;
+
+import io.choerodon.asgard.common.AbstractAsgardConsumer;
+import io.choerodon.asgard.common.ApplicationContextHelper;
+import io.choerodon.asgard.common.UpdateStatusDTO;
+import io.choerodon.asgard.schedule.annotation.JobTask;
+import io.choerodon.asgard.schedule.dto.PollScheduleInstanceDTO;
+import io.choerodon.asgard.schedule.dto.ScheduleInstanceConsumerDTO;
+import io.choerodon.asgard.schedule.feign.ScheduleConsumerClient;
public class ScheduleConsumer extends AbstractAsgardConsumer {
@@ -72,6 +69,17 @@ protected void scheduleRunning(String instance) {
}
private ScheduleInstanceConsumerDTO invoke(final ScheduleInstanceConsumerDTO data) {
+ final JobTaskInvokeBean invokeBean = invokeBeanMap.get(data.getMethod());
+ final JobTask jobTask = invokeBean.jobTask;
+ if (jobTask.enableTransaction()) {
+ return invokeWithinTransaction(data);
+ } else {
+ return invokeWithoutTransaction(data);
+ }
+
+ }
+
+ private ScheduleInstanceConsumerDTO invokeWithinTransaction(final ScheduleInstanceConsumerDTO data) {
final JobTaskInvokeBean invokeBean = invokeBeanMap.get(data.getMethod());
final JobTask jobTask = invokeBean.jobTask;
PlatformTransactionManager platformTransactionManager = getSagaTaskTransactionManager(jobTask.transactionManager());
@@ -97,6 +105,29 @@ private ScheduleInstanceConsumerDTO invoke(final ScheduleInstanceConsumerDTO dat
return data;
}
+ private ScheduleInstanceConsumerDTO invokeWithoutTransaction(final ScheduleInstanceConsumerDTO data) {
+ final JobTaskInvokeBean invokeBean = invokeBeanMap.get(data.getMethod());
+ beforeInvoke(data.getUserDetails());
+ try {
+ invokeBean.method.setAccessible(true);
+ Object result = invokeBean.method.invoke(invokeBean.object, getInputMap(data.getExecuteParams()));
+ if (result != null) {
+ result = objectMapper.writeValueAsString(result);
+ }
+ scheduleConsumerClient.updateStatus(data.getId(), new UpdateStatusDTO(data.getId(), QuartzDefinition.InstanceStatus.COMPLETED.name(),
+ resultToJson(result, objectMapper), null, data.getObjectVersionNumber()));
+ runningTasks.remove(data.getId());
+ } catch (Exception e) {
+ String errorMsg = getErrorInfoFromException(e);
+ LOGGER.info("@JobTask method: {}, id: {} invoke error", data.getMethod(), data.getId(), getLoggerException(e));
+ invokeError(data, errorMsg);
+ } finally {
+ afterInvoke();
+ }
+ return data;
+ }
+
+
private void invokeError(final PlatformTransactionManager platformTransactionManager,
final TransactionStatus status,
final ScheduleInstanceConsumerDTO data,
@@ -106,14 +137,19 @@ private void invokeError(final PlatformTransactionManager platformTransactionMan
} catch (Exception e) {
LOGGER.warn("@JobTask method: {}, id: {} transaction rollback error", data.getMethod(), data.getId(), e);
} finally {
- try {
- scheduleConsumerClient.updateStatus(data.getId(), new UpdateStatusDTO(data.getId(),
- QuartzDefinition.InstanceStatus.FAILED.name(), null, errorMsg, data.getObjectVersionNumber()));
- runningTasks.remove(data.getId());
- } catch (Exception ex) {
- LOGGER.warn("@JobTask method: {}, id: {} updateStatusFailed error, error message: {}", data.getMethod(), data.getId(), ex.getMessage());
- runningTasks.remove(data.getId());
- }
+ invokeError(data, errorMsg);
+ }
+ }
+
+ private void invokeError(final ScheduleInstanceConsumerDTO data,
+ final String errorMsg) {
+ try {
+ scheduleConsumerClient.updateStatus(data.getId(), new UpdateStatusDTO(data.getId(),
+ QuartzDefinition.InstanceStatus.FAILED.name(), null, errorMsg, data.getObjectVersionNumber()));
+ runningTasks.remove(data.getId());
+ } catch (Exception ex) {
+ LOGGER.warn("@JobTask method: {}, id: {} updateStatusFailed error, error message: {}", data.getMethod(), data.getId(), ex.getMessage());
+ runningTasks.remove(data.getId());
}
}
diff --git a/choerodon-starter-asgard/src/main/java/io/choerodon/asgard/schedule/annotation/JobTask.java b/choerodon-starter-asgard/src/main/java/io/choerodon/asgard/schedule/annotation/JobTask.java
index a0a69463..a349b0ca 100644
--- a/choerodon-starter-asgard/src/main/java/io/choerodon/asgard/schedule/annotation/JobTask.java
+++ b/choerodon-starter-asgard/src/main/java/io/choerodon/asgard/schedule/annotation/JobTask.java
@@ -5,10 +5,10 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-import io.choerodon.core.iam.ResourceLevel;
-
import org.springframework.transaction.annotation.Isolation;
+import io.choerodon.core.iam.ResourceLevel;
+
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface JobTask {
@@ -41,6 +41,13 @@
*/
boolean transactionReadOnly() default false;
+ /**
+ * 是否开启事务
+ *
+ * @return 是否开启事务
+ */
+ boolean enableTransaction() default true;
+
/**
* 事务的隔离级别
*
diff --git a/choerodon-starter-core/pom.xml b/choerodon-starter-core/pom.xml
index aa784d11..be99a099 100644
--- a/choerodon-starter-core/pom.xml
+++ b/choerodon-starter-core/pom.xml
@@ -5,16 +5,18 @@
choerodon-starter-parent
io.choerodon
- 2.0.0.RELEASE
+ 2.2.0-19-SNAPSHOT
4.0.0
choerodon-starter-core
+
org.hzero.starter
hzero-starter-mybatis-mapper
+ 1.8.1.RELEASE
org.hzero.boot
@@ -23,4 +25,4 @@
-
\ No newline at end of file
+
diff --git a/choerodon-starter-core/src/main/java/io/choerodon/core/utils/FeignFallbackUtil.java b/choerodon-starter-core/src/main/java/io/choerodon/core/utils/FeignFallbackUtil.java
new file mode 100644
index 00000000..f702efe9
--- /dev/null
+++ b/choerodon-starter-core/src/main/java/io/choerodon/core/utils/FeignFallbackUtil.java
@@ -0,0 +1,39 @@
+package io.choerodon.core.utils;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.util.Arrays;
+
+import com.alibaba.fastjson.JSON;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.Assert;
+
+/**
+ * Copyright (c) 2022. Hand Enterprise Solution Company. All right reserved.
+ *
+ * @author zongqi.hao@zknow.com
+ * @since 2022/7/13
+ */
+public class FeignFallbackUtil {
+
+ private FeignFallbackUtil() {
+ }
+
+ public static T get(Throwable cause, Class targetClass) {
+ Assert.notNull(targetClass, "feign target class could not be null!");
+ Logger logger = LoggerFactory.getLogger(targetClass);
+ InvocationHandler invocationHandler = (proxy, method, args) -> {
+ logger.error("error when call {}.{} by params{}", method.getDeclaringClass().getSimpleName(),
+ method.getName(), JSON.toJSONString(args));
+ if (cause != null) {
+ logger.error(cause.getMessage(), cause);
+ }
+ return ResponseEntity.badRequest().contentType(MediaType.APPLICATION_JSON).body("请联系运维人员");
+ };
+ return (T) Proxy.newProxyInstance(targetClass.getClassLoader(), new Class[]{targetClass}, invocationHandler);
+ }
+
+}
diff --git a/choerodon-starter-core/src/main/java/io/choerodon/core/utils/TypeUtils.java b/choerodon-starter-core/src/main/java/io/choerodon/core/utils/TypeUtils.java
new file mode 100644
index 00000000..63c24122
--- /dev/null
+++ b/choerodon-starter-core/src/main/java/io/choerodon/core/utils/TypeUtils.java
@@ -0,0 +1,99 @@
+package io.choerodon.core.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Created by younger on 2018/3/29.
+ */
+public class TypeUtils {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(TypeUtils.class);
+ public static final String SEARCH_PARAM = "searchParam";
+ public static final String PARAMS = "params";
+
+ private TypeUtils() {
+ }
+
+ /**
+ * obj转string类型
+ */
+
+ public static String objToString(Object obj) {
+ if (obj == null) {
+ return null;
+ }
+ return String.valueOf(obj);
+ }
+
+ /**
+ * obj转integer类型
+ */
+
+ public static Integer objToInteger(Object obj) {
+ if (obj == null || "".equals(obj)) {
+ return null;
+ }
+ return Integer.valueOf(String.valueOf(obj));
+ }
+
+ /**
+ * obj转long类型
+ */
+
+ public static Long objToLong(Object obj) {
+ if (obj == null || "".equals(obj)) {
+ return null;
+ }
+ return Long.valueOf(String.valueOf(obj));
+ }
+
+ /**
+ * obj转double类型
+ */
+
+ public static double objTodouble(Object obj) {
+ if (obj == null || "".equals(obj)) {
+ return 0;
+ }
+ return Double.parseDouble(String.valueOf(obj));
+ }
+
+ /**
+ * obj转int类型
+ */
+
+ public static int objToInt(Object obj) {
+ if (obj == null || "".equals(obj)) {
+ return 0;
+ }
+ return Integer.parseInt(String.valueOf(obj));
+ }
+
+ /**
+ * obj转boolean类型
+ */
+
+ public static Boolean objToBoolean(Object obj) {
+ if (obj == null || "".equals(obj)) {
+ return false;
+ }
+ return Boolean.valueOf(String.valueOf(obj));
+ }
+
+ /**
+ * 对象转换
+ *
+ * @param obj obj
+ * @param t
+ * @return t
+ */
+ public static T cast(Object obj) {
+ if (obj == null) {
+ return null;
+ } else {
+ return (T) obj;
+ }
+ }
+
+}
diff --git a/choerodon-starter-core/src/main/java/io/choerodon/mybatis/pagehelper/PageInterceptor.java b/choerodon-starter-core/src/main/java/io/choerodon/mybatis/pagehelper/PageInterceptor.java
new file mode 100644
index 00000000..2a5593d4
--- /dev/null
+++ b/choerodon-starter-core/src/main/java/io/choerodon/mybatis/pagehelper/PageInterceptor.java
@@ -0,0 +1,344 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2014-2017 abel533@gmail.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package io.choerodon.mybatis.pagehelper;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.ibatis.cache.CacheKey;
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.mapping.BoundSql;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.plugin.*;
+import org.apache.ibatis.session.ResultHandler;
+import org.apache.ibatis.session.RowBounds;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import io.choerodon.core.domain.PageInfo;
+import io.choerodon.mybatis.pagehelper.cache.Cache;
+import io.choerodon.mybatis.pagehelper.cache.CacheFactory;
+import io.choerodon.mybatis.pagehelper.domain.Sort;
+import io.choerodon.mybatis.pagehelper.exception.PageException;
+import io.choerodon.mybatis.pagehelper.page.PageCountCacher;
+import io.choerodon.mybatis.pagehelper.page.PageMethod;
+import io.choerodon.mybatis.pagehelper.parser.IOrderByParser;
+import io.choerodon.mybatis.pagehelper.util.MappedStatementUtils;
+
+
+/**
+ * todo scp 临时覆盖分页缓存内存不释放问题
+ * Mybatis - 通用分页拦截器
+ * 项目地址 : http://git.oschina.net/free/Mybatis_PageHelper
+ *
+ * @author liuzh/abel533/isea533
+ * @version 5.0.0
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+@InterceptorOrder(0)
+@Intercepts(
+ {
+ @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
+ @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
+ }
+)
+public class PageInterceptor implements Interceptor {
+ private static final String CUSTOM_COUNT_SQL_POSTFIX = "_COUNT";
+ /**
+ * 缓存count查询的ms
+ **/
+ private Cache msCountMap = null;
+ private Dialect dialect = null;
+ private IOrderByParser orderByParser;
+ private Field additionalParametersField;
+ private final PageCountCacher pageCountCacher;
+
+ private static final Logger logger = LoggerFactory.getLogger(PageInterceptor.class);
+
+ public PageInterceptor(Dialect dialect, IOrderByParser orderByParser, PageCountCacher pageCountCacher) {
+ this.dialect = dialect;
+ this.orderByParser = orderByParser;
+ this.pageCountCacher = pageCountCacher;
+ }
+
+ public PageInterceptor(Dialect dialect, Field additionalParametersField, Cache msCountMap, PageCountCacher pageCountCacher) {
+ this.dialect = dialect;
+ this.additionalParametersField = additionalParametersField;
+ this.msCountMap = msCountMap;
+ this.pageCountCacher = pageCountCacher;
+ }
+
+ @Override
+ public Object intercept(Invocation invocation) throws Throwable {
+ try {
+ Object[] args = invocation.getArgs();
+ MappedStatement ms = (MappedStatement) args[0];
+ Object parameter = args[1];
+ RowBounds rowBounds = (RowBounds) args[2];
+ ResultHandler resultHandler = (ResultHandler) args[3];
+ Executor executor = (Executor) invocation.getTarget();
+ CacheKey cacheKey;
+ BoundSql boundSql;
+ //由于逻辑关系,只会进入一次
+ if (args.length == 4) {
+ //4 个参数时
+ boundSql = ms.getBoundSql(parameter);
+ cacheKey = executor.createCacheKey(ms, parameter, rowBounds, boundSql);
+ } else {
+ //6 个参数时
+ cacheKey = (CacheKey) args[4];
+ boundSql = (BoundSql) args[5];
+ }
+ List resultList;
+ BoundSql sqlWithOrderBy = null;
+ boolean executePage = !dialect.skip(ms, parameter, rowBounds);
+ //获得ThreadLocal里面的sort参数
+ Sort sort = PageHelper.getLocalSort();
+ boolean executeSort = (sort != null);
+ //反射获取动态参数
+ Map additionalParameters = (Map) additionalParametersField.get(boundSql);
+ if (executePage && !executeSort) {
+ //只分页,count统计sql
+ if (doCount(ms, parameter, rowBounds, resultHandler, executor, boundSql, additionalParameters)) {
+ return dialect.afterPage(new ArrayList(), parameter, rowBounds);
+ }
+ //判断是否需要进行分页查询
+ DoPage doPage =
+ new DoPage(ms, parameter, rowBounds, resultHandler,
+ executor, cacheKey, boundSql, sqlWithOrderBy, additionalParameters).invoke();
+ resultList = doPage.getResultList();
+ parameter = doPage.getParameter();
+ return dialect.afterPage(resultList, parameter, rowBounds);
+ } else if (!executePage && executeSort) {
+ //只排序
+ parameter = dialect.processParameterObject(ms, parameter, boundSql, cacheKey);
+ //拼接排序order by操作
+ sqlWithOrderBy = doSort(ms, parameter, boundSql, sqlWithOrderBy, sort, executeSort);
+ //设置动态参数
+ setDynamicParam(sqlWithOrderBy, additionalParameters);
+ //执行排序查询
+ return executor.query(ms, parameter, RowBounds.DEFAULT, resultHandler, cacheKey, sqlWithOrderBy);
+ } else if (executePage && executeSort) {
+ //分页和排序
+ if (doCount(ms, parameter, rowBounds, resultHandler, executor, boundSql, additionalParameters)) {
+ return dialect.afterPage(new ArrayList(), parameter, rowBounds);
+ }
+ //拼接排序order by操作
+ sqlWithOrderBy = doSort(ms, parameter, boundSql, sqlWithOrderBy, sort, executeSort);
+ //判断是否需要进行分页查询
+ DoPage doPage =
+ new DoPage(ms, parameter, rowBounds, resultHandler, executor,
+ cacheKey, boundSql, sqlWithOrderBy, additionalParameters).invoke();
+ resultList = doPage.getResultList();
+ parameter = doPage.getParameter();
+ return dialect.afterPage(resultList, parameter, rowBounds);
+ } else {
+ //即不分页也不排序
+ //rowBounds用参数值,不使用分页插件处理时,仍然支持默认的内存分页
+ return executor.query(ms, parameter, rowBounds, resultHandler, cacheKey, boundSql);
+ }
+ } finally {
+ dialect.afterAll();
+ }
+ }
+
+ @Override
+ public Object plugin(Object target) {
+ return Plugin.wrap(target, this);
+ }
+
+ @Override
+ public void setProperties(Properties properties) {
+ dialect.setProperties(properties);
+ msCountMap = CacheFactory.createCache(properties.getProperty("msCountCache"), "ms", properties);
+ try {
+ additionalParametersField = BoundSql.class.getDeclaredField("additionalParameters");
+ additionalParametersField.setAccessible(true);
+ } catch (NoSuchFieldException e) {
+ logger.debug("NoSuchFieldException:" + e);
+ }
+ }
+
+ private class DoPage {
+ private MappedStatement ms;
+ private Object parameter;
+ private RowBounds rowBounds;
+ private ResultHandler resultHandler;
+ private Executor executor;
+ private CacheKey cacheKey;
+ private BoundSql boundSql;
+ private BoundSql sqlWithOrderBy;
+ private Map additionalParameters;
+ private List resultList;
+
+ public DoPage(MappedStatement ms, Object parameter, RowBounds rowBounds,
+ ResultHandler resultHandler, Executor executor, CacheKey cacheKey,
+ BoundSql boundSql, BoundSql sqlWithOrderBy, Map additionalParameters) {
+ this.ms = ms;
+ this.parameter = parameter;
+ this.rowBounds = rowBounds;
+ this.resultHandler = resultHandler;
+ this.executor = executor;
+ this.cacheKey = cacheKey;
+ this.boundSql = boundSql;
+ this.sqlWithOrderBy = sqlWithOrderBy;
+ this.additionalParameters = additionalParameters;
+ }
+
+ public Object getParameter() {
+ return parameter;
+ }
+
+ public List getResultList() {
+ return resultList;
+ }
+
+ public DoPage invoke() throws java.sql.SQLException {
+ if (dialect.beforePage(ms, parameter, rowBounds)) {
+ //生成分页的缓存 key
+ CacheKey pageKey = cacheKey;
+ //处理参数对象
+ parameter = dialect.processParameterObject(ms, parameter, boundSql, pageKey);
+ //调用方言获取分页 sql
+ String pageSql;
+ if (sqlWithOrderBy != null) {
+ pageSql = dialect.getPageSql(ms, sqlWithOrderBy, parameter, rowBounds, pageKey);
+ } else {
+ pageSql = dialect.getPageSql(ms, boundSql, parameter, rowBounds, pageKey);
+ }
+ BoundSql pageBoundSql =
+ new BoundSql(ms.getConfiguration(), pageSql, boundSql.getParameterMappings(), parameter);
+ setDynamicParam(pageBoundSql, additionalParameters);
+ //执行分页查询
+ resultList = executor.query(ms, parameter, RowBounds.DEFAULT, resultHandler, pageKey, pageBoundSql);
+ } else {
+ if (sqlWithOrderBy != null) {
+ setDynamicParam(sqlWithOrderBy, additionalParameters);
+ resultList =
+ executor.query(ms, parameter, RowBounds.DEFAULT, resultHandler, cacheKey, sqlWithOrderBy);
+ } else {
+ setDynamicParam(boundSql, additionalParameters);
+ resultList = executor.query(ms, parameter, RowBounds.DEFAULT, resultHandler, cacheKey, boundSql);
+ }
+ }
+ return this;
+ }
+ }
+
+ private void setDynamicParam(BoundSql boundSql, Map additionalParameters) {
+ for (Map.Entry entry : additionalParameters.entrySet()) {
+ boundSql.setAdditionalParameter(entry.getKey(), entry.getValue());
+ }
+ }
+
+ private BoundSql doSort(MappedStatement ms, Object parameter, BoundSql boundSql,
+ BoundSql sqlWithOrderBy, Sort sort, boolean executeSort) {
+ if (executeSort) {
+ //拼接order by并不会影响count查询,这里不对count查询的sql拼接order by
+ //转换sort对象为sql字符串
+ String orderBySql = orderByParser.sortToString(sort, ms);
+ String sql = boundSql.getSql();
+ if (orderByParser.containOrderBy(sql)) {
+ throw new PageException("the select sql can not contains order by while using doPageAndSort or doSort");
+ }
+ sql = sql + " order by " + orderBySql;
+ sqlWithOrderBy = new BoundSql(ms.getConfiguration(), sql, boundSql.getParameterMappings(), parameter);
+ }
+ return sqlWithOrderBy;
+ }
+
+ private boolean doCount(MappedStatement ms, Object parameter, RowBounds rowBounds,
+ ResultHandler resultHandler, Executor executor, BoundSql boundSql,
+ Map additionalParameters) throws Exception {
+ //判断是否需要进行 count 查询
+ if (dialect.beforeCount(ms, parameter, rowBounds)) {
+ // 若已经指定了total,跳过countSql执行
+ PageInfo pageInfo = PageMethod.getLocalPage();
+ if (pageInfo != null && pageInfo.getTotal() > 0) {
+ //处理查询总数
+ long count = pageInfo.getTotal();
+ //返回 true 时继续分页查询,false 时直接返回
+ if (!dialect.afterCount(count, parameter, rowBounds)) {
+ //当查询总数为 0 时,直接返回空的结果
+ return true;
+ }
+ return false;
+ }
+
+ MappedStatement customCountMs = null;
+ try {
+ customCountMs = ms.getConfiguration().getMappedStatement(ms.getId() + CUSTOM_COUNT_SQL_POSTFIX);
+ } catch (Exception e) {
+ //ignore
+ }
+
+ Long count;
+ if (customCountMs != null) {
+ // 如果已经缓存查询总数,则使用缓存值
+ MappedStatement countMs = customCountMs;
+ count = pageCountCacher.getCount(countMs.getId(), pageInfo, (k) -> {
+ //自定义Count SQL
+ Object countResultList = executor.query(countMs, parameter, RowBounds.DEFAULT, resultHandler);
+ return (Long) ((List) countResultList).get(0);
+ });
+ } else {
+ //自动生成Count SQL
+ CacheKey countKey = executor.createCacheKey(ms, parameter, RowBounds.DEFAULT, boundSql);
+ countKey.update(MappedStatementUtils.COUNT);
+ MappedStatement countMs = msCountMap.get(countKey);
+ if (countMs == null) {
+ //根据当前的 ms 创建一个返回值为 Long 类型的 ms
+ countMs = MappedStatementUtils.newCountMappedStatement(ms);
+ // todo 唯一覆盖
+ msCountMap.put(countKey.clone(), countMs);
+ }
+ //调用方言获取 count sql
+ String countSql = dialect.getCountSql(ms, boundSql, parameter, rowBounds, countKey);
+ BoundSql countBoundSql =
+ new BoundSql(ms.getConfiguration(), countSql, boundSql.getParameterMappings(), parameter);
+ //当使用动态 SQL 时,可能会产生临时的参数,这些参数需要手动设置到新的 BoundSql 中
+ setDynamicParam(countBoundSql, additionalParameters);
+ MappedStatement finalCountMs = countMs;
+ count = pageCountCacher.getCount(countMs.getId(), parameter, (k) -> {
+ //执行 count 查询
+ Object countResultList = executor.query(finalCountMs, parameter, RowBounds.DEFAULT, resultHandler, countKey, countBoundSql);
+ return (Long) ((List) countResultList).get(0);
+ });
+ }
+
+ //处理查询总数
+ //返回 true 时继续分页查询,false 时直接返回
+ if (!dialect.afterCount(count, parameter, rowBounds)) {
+ //当查询总数为 0 时,直接返回空的结果
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/choerodon-starter-fragment/pom.xml b/choerodon-starter-fragment/pom.xml
index 77f5ddce..67b1bd55 100644
--- a/choerodon-starter-fragment/pom.xml
+++ b/choerodon-starter-fragment/pom.xml
@@ -5,7 +5,7 @@
choerodon-starter-parent
io.choerodon
- 2.0.0.RELEASE
+ 2.2.0-19-SNAPSHOT
4.0.0
@@ -23,4 +23,4 @@
hzero-starter-core
-
\ No newline at end of file
+
diff --git a/choerodon-starter-limit/pom.xml b/choerodon-starter-limit/pom.xml
index e7a88c25..75870a93 100644
--- a/choerodon-starter-limit/pom.xml
+++ b/choerodon-starter-limit/pom.xml
@@ -4,7 +4,7 @@
choerodon-starter-parent
io.choerodon
- 2.0.0.RELEASE
+ 2.2.0-19-SNAPSHOT
4.0.0
diff --git a/choerodon-starter-nacos-client/pom.xml b/choerodon-starter-nacos-client/pom.xml
index e47ecbb0..c0ff8196 100644
--- a/choerodon-starter-nacos-client/pom.xml
+++ b/choerodon-starter-nacos-client/pom.xml
@@ -19,7 +19,7 @@
choerodon-starter-parent
io.choerodon
- 2.0.0.RELEASE
+ 2.2.0-19-SNAPSHOT
4.0.0
@@ -39,7 +39,7 @@
2.12.2
3.5.0
1.7.30
- 1.2.3
+ 1.2.9
diff --git a/choerodon-starter-only-office/pom.xml b/choerodon-starter-only-office/pom.xml
index 4a43f500..2c465ef2 100644
--- a/choerodon-starter-only-office/pom.xml
+++ b/choerodon-starter-only-office/pom.xml
@@ -5,12 +5,12 @@
choerodon-starter-parent
io.choerodon
- 2.0.0.RELEASE
+ 2.2.0-19-SNAPSHOT
4.0.0
choerodon-starter-only-office
- 2.0.0.RELEASE
+ 2.2.0-19-SNAPSHOT
@@ -53,4 +53,4 @@
-
\ No newline at end of file
+
diff --git a/choerodon-tool-liquibase/pom.xml b/choerodon-tool-liquibase/pom.xml
index 36dfcbf0..f4958f4e 100644
--- a/choerodon-tool-liquibase/pom.xml
+++ b/choerodon-tool-liquibase/pom.xml
@@ -5,7 +5,7 @@
io.choerodon
choerodon-starter-parent
- 2.0.0.RELEASE
+ 2.2.0-19-SNAPSHOT
choerodon-tool-liquibase
diff --git a/pom.xml b/pom.xml
index 2762ece1..9b6785e0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,16 +6,15 @@
io.choerodon
choerodon-starter-parent
- 2.0.0.RELEASE
+ 2.2.0-19-SNAPSHOT
pom
- org.hzero
- hzero-parent
- 1.8.3.RELEASE
+ org.hzero.starter
+ hzero-starter-parent
+ 1.8.0.RELEASE
-
UTF-8
1.8