fix(测试跟踪): 功能用例列表查询与批量删除性能优化

--bug=1013542 --user=陈建星 【测试跟踪】功能用例删除模块用例过多时,接口响应时间过长,需要优化性能 https://www.tapd.cn/55049933/s/1173692
--bug=1013347 --user=陈建星 【测试跟踪】windows电脑 8G 内存,测试跟踪功能用例 每条50页,翻页响应时间过长 需要优化性能 https://www.tapd.cn/55049933/s/1174023
This commit is contained in:
chenjianxing 2022-06-06 16:54:04 +08:00 committed by jianxing
parent 22340b870e
commit 7dc82c72dc
5 changed files with 92 additions and 34 deletions

View File

@ -6,6 +6,7 @@ import io.metersphere.controller.request.BaseQueryRequest;
import io.metersphere.dto.RelationshipGraphData;
import io.metersphere.track.dto.CustomFieldResourceCompatibleDTO;
import io.metersphere.track.dto.TestCaseDTO;
import io.metersphere.track.request.testcase.DeleteTestCaseRequest;
import io.metersphere.track.request.testcase.QueryTestCaseRequest;
import io.metersphere.track.request.testcase.TestCaseBatchRequest;
import io.metersphere.track.response.TrackCountResult;
@ -109,7 +110,7 @@ public interface ExtTestCaseMapper {
List<TestCaseWithBLOBs> getCustomFieldsByIds(@Param("ids") List<String> ids);
int deleteToGc(@Param("request") TestCase testCase);
int deleteToGc(@Param("request") DeleteTestCaseRequest testCase);
int deletePublic(@Param("request") TestCase testCase);

View File

@ -560,11 +560,11 @@
</if>
<if test="request.statusIsNot != null">
and (test_case.status is null or test_case.status != #{request.statusIsNot})
and test_case.status != #{request.statusIsNot}
</if>
<if test="request.notEqStatus != null">
and (test_case.status is null or test_case.status != #{request.notEqStatus})
and test_case.status != #{request.notEqStatus}
</if>
<if test="request.casePublic != null and request.casePublic == true">
and test_case.case_public = true
@ -621,11 +621,11 @@
</if>
<if test="request.statusIsNot != null">
and (test_case.status is null or test_case.status != #{request.statusIsNot})
and test_case.status != #{request.statusIsNot}
</if>
<if test="request.notEqStatus != null">
and (test_case.status is null or test_case.status != #{request.notEqStatus})
and test_case.status != #{request.notEqStatus}
</if>
<if test="request.name != null">
and (test_case.name like CONCAT('%', #{request.name},'%')
@ -675,7 +675,7 @@
SELECT test_case.priority as groupField, count(DISTINCT ref_id) AS countNumber
FROM test_case
WHERE project_id = #{projectId}
AND (test_case.status IS NULL OR test_case.status != 'Trash')
AND test_case.status != 'Trash'
and latest = true
GROUP BY test_case.priority
</select>
@ -686,7 +686,7 @@
</select>
<select id="countStatus" resultType="io.metersphere.track.response.TrackCountResult">
SELECT review_status AS groupField,count(id) AS countNumber FROM test_case
WHERE project_id = #{projectId} and (test_case.status != 'Trash' or test_case.status is null) and latest = 1
WHERE project_id = #{projectId} and test_case.status != 'Trash' and latest = 1
GROUP BY test_case.review_status
</select>
@ -887,7 +887,7 @@
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
and (test_case.status != 'Trash' or test_case.status is NULL);
and test_case.status != 'Trash';
</select>
<select id="countByIds" resultType="java.lang.Integer">
select count(id)
@ -896,7 +896,7 @@
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
and (test_case.status != 'Trash' or test_case.status is NULL);
and test_case.status != 'Trash';
</select>
<update id="deleteToGc">
@ -905,7 +905,24 @@
status = 'Trash',
delete_time = #{request.deleteTime},
delete_user_id = #{request.deleteUserId}
where ref_id = (select a.ref_id from (select ref_id from test_case where id = #{request.id}) a )
where ref_id in (
select a.ref_id from (
select ref_id from test_case
<where>
<if test="request.id != null and request.id != ''">
id = #{request.id}
</if>
<if test="request.ids != null and request.ids.size() != 0">
and id in
<foreach collection="request.ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</if>
</where>
) a
)
</update>
<update id="deletePublic">
@ -936,7 +953,7 @@
update test_case
set
original_status = 'Underway'
where (original_status IS NULL OR original_status = 'Trash') AND id in
where (original_status = '' OR original_status = 'Trash') AND id in
<foreach collection="ids" item="v" separator="," open="(" close=")">
#{v}
</foreach>
@ -966,7 +983,7 @@
from project
where workspace_id = #{workSpaceId})
and case_public = true
and (test_case.status != 'Trash' or test_case.status is NULL)
and test_case.status != 'Trash'
</select>
<select id="trashCount" resultType="java.lang.Long">

View File

@ -0,0 +1,13 @@
package io.metersphere.track.request.testcase;
import io.metersphere.base.domain.TestCase;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class DeleteTestCaseRequest extends TestCase {
private List<String> ids;
}

View File

@ -232,11 +232,34 @@ public class TestCaseService {
updateRequest.setProjectId(request.getProjectId());
updateRequest.setTestCaseId(request.getId());
Project project = projectService.getProjectById(request.getProjectId());
updateRequest.setWorkspaceId(project.getWorkspaceId());
List<AbstractIssuePlatform> platformList = getAddPlatforms(updateRequest);
platformList.forEach(platform -> {
platform.updateDemandHyperLink(request, project, type);
});
if (StringUtils.equals(project.getPlatform(), IssuesManagePlatform.AzureDevops.name())) {
updateRequest.setWorkspaceId(project.getWorkspaceId());
List<AbstractIssuePlatform> platformList = getAddPlatforms(updateRequest);
platformList.forEach(platform -> {
platform.updateDemandHyperLink(request, project, type);
});
}
}
public void addDemandHyperLinkBatch(List<String> testcaseIds) {
if (CollectionUtils.isEmpty(testcaseIds)) {
return;
}
TestCaseWithBLOBs testCase = testCaseMapper.selectByPrimaryKey(testcaseIds.get(0));
// 同步删除用例与需求的关联关系
Project project = projectService.getProjectById(testCase.getProjectId());
// AzureDevops 才处理
if (StringUtils.equals(project.getPlatform(), IssuesManagePlatform.AzureDevops.name())) {
testcaseIds.forEach(id -> {
TestCaseWithBLOBs testCaseWithBLOBs = testCaseMapper.selectByPrimaryKey(testcaseIds.get(0));
if (testCaseWithBLOBs != null) {
EditTestCaseRequest request = new EditTestCaseRequest();
BeanUtils.copyBean(request, testCaseWithBLOBs);
addDemandHyperLink(request, "delete");
}
});
}
}
private List<AbstractIssuePlatform> getAddPlatforms(IssuesRequest request) {
@ -612,7 +635,25 @@ public class TestCaseService {
addDemandHyperLink(request, "delete");
}
return extTestCaseMapper.deleteToGc(testCase);
DeleteTestCaseRequest request = new DeleteTestCaseRequest();
BeanUtils.copyBean(request, testCase);
return extTestCaseMapper.deleteToGc(request);
}
public int deleteToGcBatch(List<String> ids) {
if (CollectionUtils.isEmpty(ids)) {
return 0;
}
TestCase testCase = new TestCase();
testCase.setDeleteUserId(SessionUtils.getUserId());
testCase.setDeleteTime(System.currentTimeMillis());
addDemandHyperLinkBatch(ids);
DeleteTestCaseRequest request = new DeleteTestCaseRequest();
BeanUtils.copyBean(request, testCase);
request.setIds(ids);
return extTestCaseMapper.deleteToGc(request);
}
public List<TestCaseDTO> listTestCase(QueryTestCaseRequest request) {
@ -678,11 +719,6 @@ public class TestCaseService {
public void setDefaultOrder(QueryTestCaseRequest request) {
List<OrderRequest> orders = ServiceUtils.getDefaultSortOrder(request.getOrders());
OrderRequest order = new OrderRequest();
// 对模板导入的测试用例排序
order.setName("sort");
order.setType("desc");
orders.add(order);
orders.forEach(i -> i.setPrefix("test_case"));
request.setOrders(orders);
}
@ -1058,7 +1094,7 @@ public class TestCaseService {
num++;
testCase.setReviewStatus(TestCaseReviewStatus.Prepare.name());
testCase.setStatus(TestCaseReviewStatus.Prepare.name());
testCase.setOrder(new Long(testCases.size() - (num - beforeInsertId)) * ServiceUtils.ORDER_STEP);
testCase.setOrder(Long.valueOf(testCases.size() - (num - beforeInsertId)) * ServiceUtils.ORDER_STEP);
testCase.setRefId(testCase.getId());
testCase.setVersionId(request.getVersionId());
testCase.setLatest(true);
@ -1131,11 +1167,9 @@ public class TestCaseService {
try {
if (!testCases.isEmpty()) {
AtomicInteger sort = new AtomicInteger();
testCases.forEach(testcase -> {
testcase.setUpdateTime(System.currentTimeMillis());
testcase.setNodeId(nodePathMap.get(testcase.getNodePath()));
testcase.setSort(sort.getAndIncrement());
TestCase dbCase = request.isUseCustomId() ? customIdMap.get(testcase.getCustomNum()) : customIdMap.get(testcase.getNum());
testcase.setId(dbCase.getId());
testcase.setRefId(dbCase.getRefId());
@ -2221,14 +2255,6 @@ public class TestCaseService {
}
}
public void deleteToGcBatch(List<String> ids) {
if (CollectionUtils.isNotEmpty(ids)) {
for (String id : ids) {
this.deleteTestCaseToGc(id);
}
}
}
public void deleteToGcBatchPublic(TestCaseBatchRequest request) {
ServiceUtils.getSelectAllIds(request, request.getCondition(),
(query) -> extTestCaseMapper.selectPublicIds(query));

View File

@ -0,0 +1 @@
-- 初始化 sql