fix(测试跟踪): 功能用例批量编辑性能优化
--bug=1014258 --user=陈建星 【测试跟踪】功能列表用例条数过多时,批量编辑接口性能需要优化 {#_orginal_url#}
This commit is contained in:
parent
e050476c7c
commit
d18ed3d200
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.base.mapper.ext;
|
||||
|
||||
import io.metersphere.base.domain.ext.CustomFieldResource;
|
||||
import io.metersphere.dto.CustomFieldResourceDTO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -20,4 +21,8 @@ public interface ExtCustomFieldResourceMapper {
|
|||
List<CustomFieldResource> getByResourceIds(@Param("tableName") String tableName, @Param("resourceIds") List<String> resourceIds);
|
||||
|
||||
long countFieldResource(@Param("tableName") String tableName, @Param("resourceId") String resourceId, @Param("fieldId") String field_id);
|
||||
|
||||
int batchUpdateByResourceIds(@Param("tableName") String tableName, @Param("resourceIds") List<String> resourceIds, @Param("record") CustomFieldResourceDTO customField);
|
||||
|
||||
void batchInsertIfNotExists(@Param("tableName") String tableName, @Param("record") CustomFieldResourceDTO customField);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,12 @@
|
|||
</insert>
|
||||
<update id="updateByPrimaryKeySelective">
|
||||
update ${tableName}
|
||||
<include refid="updateValueColumn"/>
|
||||
where resource_id = #{record.resourceId,jdbcType=VARCHAR}
|
||||
and field_id = #{record.fieldId,jdbcType=VARCHAR}
|
||||
</update>
|
||||
|
||||
<sql id="updateValueColumn">
|
||||
<set>
|
||||
<if test="record.value != null">
|
||||
`value` = #{record.value,jdbcType=VARCHAR},
|
||||
|
@ -18,8 +24,28 @@
|
|||
text_value = #{record.textValue,jdbcType=LONGVARCHAR},
|
||||
</if>
|
||||
</set>
|
||||
where resource_id = #{record.resourceId,jdbcType=VARCHAR}
|
||||
and field_id = #{record.fieldId,jdbcType=VARCHAR}
|
||||
</sql>
|
||||
<update id="batchUpdateByResourceIds">
|
||||
update ${tableName}
|
||||
<include refid="updateValueColumn"/>
|
||||
where resource_id in
|
||||
<foreach collection="resourceIds" item="resourceId" separator="," open="(" close=")">
|
||||
#{resourceId}
|
||||
</foreach>
|
||||
</update>
|
||||
<update id="batchInsertIfNotExists">
|
||||
INSERT INTO ${tableName} (resource_id, field_id, `value`, text_value)
|
||||
SELECT
|
||||
'${record.resourceId}',
|
||||
'${record.fieldId}',
|
||||
'${record.value}',
|
||||
'${record.textValue}'
|
||||
FROM DUAL
|
||||
WHERE NOT EXISTS(
|
||||
select resource_id
|
||||
from ${tableName}
|
||||
where resource_id = #{record.resourceId} and field_id = #{record.fieldId}
|
||||
)
|
||||
</update>
|
||||
<delete id="deleteByResourceId">
|
||||
delete from ${tableName}
|
||||
|
|
|
@ -21,10 +21,7 @@ import org.mybatis.spring.SqlSessionUtils;
|
|||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ServiceUtils {
|
||||
|
@ -302,6 +299,26 @@ public class ServiceUtils {
|
|||
return sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量操作
|
||||
*/
|
||||
public static void batchOperate(List data, int batchSize, Class mapperClazz, BiConsumer operateFunc) {
|
||||
if (CollectionUtils.isEmpty(data)) {
|
||||
return;
|
||||
}
|
||||
SqlSessionFactory sqlSessionFactory = CommonBeanFactory.getBean(SqlSessionFactory.class);
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
Object mapper = sqlSession.getMapper(mapperClazz);
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
operateFunc.accept(data.get(i), mapper);
|
||||
if (i % batchSize == 0) {
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
}
|
||||
sqlSession.flushStatements();
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||
}
|
||||
|
||||
public static String getCopyName(String name) {
|
||||
return "copy_" + name + "_" + UUID.randomUUID().toString().substring(0, 4);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package io.metersphere.commons.utils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class SubListUtil {
|
||||
|
||||
/**
|
||||
* 将较长的数组截断成较短的数组进行批处理
|
||||
*/
|
||||
public static void dealForSubList(List totalList, Integer batchSize, Consumer<List> subFunc) {
|
||||
int count = totalList.size();
|
||||
int iteratorCount = count / batchSize;
|
||||
for (int i = 0; i <= iteratorCount; i++) {
|
||||
int endIndex, startIndex;
|
||||
startIndex = i * batchSize;
|
||||
endIndex = ((endIndex = (i + 1) * batchSize) > count) ? count : endIndex;
|
||||
if (endIndex == startIndex) {
|
||||
break;
|
||||
}
|
||||
List subList = totalList.subList(startIndex, endIndex);
|
||||
subFunc.accept(subList);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -15,9 +15,11 @@ import io.metersphere.commons.constants.TemplateConstants;
|
|||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.ServiceUtils;
|
||||
import io.metersphere.commons.utils.SubListUtil;
|
||||
import io.metersphere.controller.request.customfield.CustomFieldResourceRequest;
|
||||
import io.metersphere.dto.CustomFieldDao;
|
||||
import io.metersphere.dto.CustomFieldItemDTO;
|
||||
import io.metersphere.dto.CustomFieldResourceDTO;
|
||||
import io.metersphere.track.dto.CustomFieldResourceCompatibleDTO;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -130,6 +132,21 @@ public class CustomFieldResourceService {
|
|||
return extCustomFieldResourceMapper.getByResourceId(tableName, resourceId);
|
||||
}
|
||||
|
||||
public void batchUpdateByResourceIds(String tableName, List<String> resourceIds, CustomFieldResourceDTO customField) {
|
||||
if (CollectionUtils.isEmpty(resourceIds)) {
|
||||
return;
|
||||
}
|
||||
SubListUtil.dealForSubList(resourceIds, 5000, (subIds) ->
|
||||
extCustomFieldResourceMapper.batchUpdateByResourceIds(tableName, subIds, customField));
|
||||
}
|
||||
|
||||
public void batchInsertIfNotExists(String tableName, List<String> resourceIds, CustomFieldResourceDTO customField) {
|
||||
ServiceUtils.batchOperate(resourceIds, 5000, ExtCustomFieldResourceMapper.class, (resourceId, batchMapper) -> {
|
||||
customField.setResourceId((String) resourceId);
|
||||
((ExtCustomFieldResourceMapper) batchMapper).batchInsertIfNotExists(tableName, customField);
|
||||
});
|
||||
}
|
||||
|
||||
protected List<CustomFieldResource> getByResourceIds(String tableName, List<String> resourceIds) {
|
||||
if (CollectionUtils.isEmpty(resourceIds)) {
|
||||
return new ArrayList<>();
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.metersphere.service;
|
|||
|
||||
import io.metersphere.base.domain.ext.CustomFieldResource;
|
||||
import io.metersphere.dto.CustomFieldDao;
|
||||
import io.metersphere.dto.CustomFieldResourceDTO;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
@ -45,4 +46,12 @@ public class CustomFieldTestCaseService extends CustomFieldResourceService {
|
|||
public List<CustomFieldResource> getByResourceId(String resourceId) {
|
||||
return super.getByResourceId(TABLE_NAME, resourceId);
|
||||
}
|
||||
|
||||
public void batchUpdateByResourceIds(List<String> resourceIds, CustomFieldResourceDTO customField) {
|
||||
super.batchUpdateByResourceIds(TABLE_NAME, resourceIds, customField);
|
||||
}
|
||||
|
||||
public void batchInsertIfNotExists(List<String> ids, CustomFieldResourceDTO customField) {
|
||||
super.batchInsertIfNotExists(TABLE_NAME, ids, customField);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1500,6 +1500,9 @@ public class TestCaseService {
|
|||
}
|
||||
|
||||
public List<TestCaseDTO> findByBatchRequest(TestCaseBatchRequest request) {
|
||||
if (!request.getCondition().isSelectAll()) {
|
||||
request.getCondition().setIds(request.getIds());
|
||||
}
|
||||
return listTestCase(request.getCondition(), true);
|
||||
}
|
||||
|
||||
|
@ -1717,6 +1720,7 @@ public class TestCaseService {
|
|||
String name = customField.getName();
|
||||
String value = JSONObject.parse(customField.getValue()).toString();
|
||||
TestCaseWithBLOBs testCaseWithBLOBs = new TestCaseWithBLOBs();
|
||||
testCaseWithBLOBs.setUpdateTime(System.currentTimeMillis());
|
||||
|
||||
if (StringUtils.equalsAnyIgnoreCase(name, "用例等级")) {
|
||||
testCaseWithBLOBs.setPriority(value);
|
||||
|
@ -1733,26 +1737,17 @@ public class TestCaseService {
|
|||
if (CollectionUtils.isEmpty(request.getIds())) {
|
||||
return;
|
||||
}
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
TestCaseMapper mapper = sqlSession.getMapper(TestCaseMapper.class);
|
||||
List<TestCaseWithBLOBs> testCases = extTestCaseMapper.getCustomFieldsByIds(request.getIds());
|
||||
for (int i = 0; i < testCases.size(); i++) {
|
||||
TestCaseWithBLOBs testCase = testCases.get(i);
|
||||
customField.setResourceId(testCase.getId());
|
||||
int row = customFieldTestCaseService.updateByPrimaryKeySelective(customField);
|
||||
if (row < 1) {
|
||||
customFieldTestCaseService.insert(customField);
|
||||
}
|
||||
testCase.setUpdateTime(System.currentTimeMillis());
|
||||
TestCaseExample example = new TestCaseExample();
|
||||
example.createCriteria().andIdEqualTo(testCase.getId());
|
||||
mapper.updateByExampleSelective(testCase, example);
|
||||
if (i % 1000 == 0) {
|
||||
sqlSession.flushStatements();
|
||||
}
|
||||
|
||||
customFieldTestCaseService.batchUpdateByResourceIds(request.getIds(), customField);
|
||||
// 如果没有字段,则添加
|
||||
customFieldTestCaseService.batchInsertIfNotExists(request.getIds(), customField);
|
||||
|
||||
if (request.getCondition().isSelectAll()) {
|
||||
// 如果全选,去掉这个查询条件,避免ids过长
|
||||
request.getCondition().setIds(null);
|
||||
}
|
||||
sqlSession.flushStatements();
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||
// 更新修改时间
|
||||
bathUpdateByCondition(request, testCaseWithBLOBs);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue