优化分类树加载逻辑,新增批量查询子节点接口以减少数据库往返,提升性能。重构相关服务和控制器,确保系统的可维护性和扩展性。
This commit is contained in:
@@ -416,13 +416,7 @@ public class SysCategoryController {
|
||||
* 递归求子节点 同步加载用到
|
||||
*/
|
||||
private void loadAllCategoryChildren(List<TreeSelectModel> ls) {
|
||||
for (TreeSelectModel tsm : ls) {
|
||||
List<TreeSelectModel> temp = this.sysCategoryService.queryListByPid(tsm.getKey());
|
||||
if(temp!=null && temp.size()>0) {
|
||||
tsm.setChildren(temp);
|
||||
loadAllCategoryChildren(temp);
|
||||
}
|
||||
}
|
||||
this.sysCategoryService.fillCategoryChildrenBatch(ls);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,6 +28,11 @@ public interface SysCategoryMapper extends BaseMapper<SysCategory> {
|
||||
*/
|
||||
public List<TreeSelectModel> queryListByPid(@Param("pid") String pid,@Param("query") Map<String, String> query);
|
||||
|
||||
/**
|
||||
* 批量按父 id 查询子节点(树同步加载按层拉取,避免 N+1)
|
||||
*/
|
||||
List<TreeSelectModel> queryListByPidIn(@Param("pids") List<String> pids, @Param("query") Map<String, String> query);
|
||||
|
||||
/**
|
||||
* 通过code查询分类字典表
|
||||
* @param code
|
||||
|
||||
@@ -33,5 +33,36 @@
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="queryListByPidIn" resultType="org.jeecg.modules.system.model.TreeSelectModel">
|
||||
select code,
|
||||
name as "title",
|
||||
id as "key",
|
||||
(case when has_child = '1' then 0 else 1 end) as isLeaf,
|
||||
pid as parentId
|
||||
from sys_category
|
||||
where pid in
|
||||
<foreach collection="pids" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
<if test="query!= null">
|
||||
<if test="query.code !=null and query.code != ''">
|
||||
and code = #{query.code}
|
||||
</if>
|
||||
<if test="query.name !=null and query.name != ''">
|
||||
and name = #{query.name}
|
||||
</if>
|
||||
<if test="query.id !=null and query.id != ''">
|
||||
and id = #{query.id}
|
||||
</if>
|
||||
<if test="query.createBy !=null and query.createBy != ''">
|
||||
and create_by = #{query.createBy}
|
||||
</if>
|
||||
<if test="query.sysOrgCode !=null and query.sysOrgCode != ''">
|
||||
and sys_org_code = #{query.sysOrgCode}
|
||||
</if>
|
||||
</if>
|
||||
order by code
|
||||
</select>
|
||||
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -98,4 +98,11 @@ public interface ISysCategoryService extends IService<SysCategory> {
|
||||
*/
|
||||
List<String> loadDictItemByNames(String names, boolean delNotExist);
|
||||
|
||||
/**
|
||||
* 按层批量补全子节点(替代逐节点递归 queryListByPid,显著减少数据库往返)
|
||||
*
|
||||
* @param nodes 首层节点列表(通常来自 {@link #queryListByCode})
|
||||
*/
|
||||
void fillCategoryChildrenBatch(List<TreeSelectModel> nodes);
|
||||
|
||||
}
|
||||
|
||||
@@ -126,6 +126,37 @@ public class SysCategoryServiceImpl extends ServiceImpl<SysCategoryMapper, SysCa
|
||||
return baseMapper.queryListByPid(pid,condition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillCategoryChildrenBatch(List<TreeSelectModel> nodes) {
|
||||
if (nodes == null || nodes.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<TreeSelectModel> frontier = new ArrayList<>(nodes);
|
||||
while (!frontier.isEmpty()) {
|
||||
List<String> pids = frontier.stream().map(TreeSelectModel::getKey).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
if (pids.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
List<TreeSelectModel> allChildren = baseMapper.queryListByPidIn(pids, null);
|
||||
if (allChildren == null || allChildren.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
Map<String, List<TreeSelectModel>> byParent = allChildren.stream().collect(Collectors.groupingBy(TreeSelectModel::getParentId));
|
||||
List<TreeSelectModel> nextFrontier = new ArrayList<>();
|
||||
for (TreeSelectModel parent : frontier) {
|
||||
List<TreeSelectModel> ch = byParent.get(parent.getKey());
|
||||
if (ch != null && !ch.isEmpty()) {
|
||||
parent.setChildren(ch);
|
||||
nextFrontier.addAll(ch);
|
||||
}
|
||||
}
|
||||
if (nextFrontier.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
frontier = nextFrontier;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String queryIdByCode(String code) {
|
||||
return baseMapper.queryIdByCode(code);
|
||||
|
||||
Reference in New Issue
Block a user