本文已参与「新人创作礼」活动,一起开启掘金创作之路。
这个前面主要在描述代码场景,您要是脾气暴躁 比较着急,请直接看最后一段代码区!
sysChannelMapper.selectListWithOrg(req);
req结构:
public class SelectChannelTreeDTO {
@ApiModelProperty(value = "是否删除 0正常 1删除 不传则不限制此条件")
private String isDelete;
@ApiModelProperty(value = "是否启用 0正常 1禁用 不传则不限制此条件")
private String status;
@ApiModelProperty(value = "组织ID 必要条件")
private String orgId;
private List<String> orgList;
}
有一个list!!
预期效果: org_id in (1,3,4,5,6)
<select id="selectListWithOrg" resultType="com.example.first.modules.channel.model.SysChannel">
SELECT
c.*
FROM
sys_channel c
LEFT JOIN (
SELECT DISTINCT
(soc.channel_id) channel_id,
soc.org_id
FROM
sys_org_channel_relation soc
) sr ON sr.channel_id = c.id
<where>
<if test="req.orgList != null and req.orgList.size() > 0">
org_id in
<foreach item="item" collection="req.orgList" index="index" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="req.isDelete != null and req.isDelete != ''">
AND c.is_delete = #{req.isDelete}
</if>
<if test="req.status != null and req.status != ''">
AND c.status = #{req.status}
</if>
</where>
ORDER BY
c.sort DESC
</select>
这段list参数的处理:
<if test="req.orgList != null and req.orgList.size() > 0">
org_id in
<foreach item="item" collection="req.orgList" index="index" open="(" separator="," close=")">
#{item}
</foreach>
</if>
对规律的HashMap 做成List:
private List<HashMap<String, Object>> getselectList(
HashMap<String, Object> channelMap
) {
List<HashMap<String, Object>> channelList = new ArrayList<>();
if(channelMap.keySet() != null){
Iterator iterator = channelMap.keySet().iterator();
while (iterator.hasNext()) {
String key = (String) iterator.next();
channelList.add((HashMap<String, Object>) channelMap.get(key));
}
}
return channelList;
}
单表父子层关联关系:
做一个递归存储器(存储器需要在递归逻辑外面声明哦)
/**
* 递归存储器
*/
private List<String> allSons = new ArrayList<>();
递归算法
//不要出现某个节点的parent_id的为其子辈 此类脏数据不适合这个判断条件 也可以消耗更多的性能去排除这种可能
List<String> getAllSons(List<SysChannel> channels,String pid){
for(SysChannel channel:channels){
//防止出现parentid = id 的脏数据死循环
if( ""== channel.getParentId() || null == channel.getParentId() || channel.getParentId().equals(channel.getId())){
continue;
}else{
if( pid.equals(channel.getParentId())){
//channels.remove(channel);//遍历完了这一条 把这条List移除提高效率 这行没测试需要测试哦
//递归遍历下一级
getAllSons(channels,channel.getId());
allSons.add(channel.getId());
}
}
}
return allSons;
}
基于单个id返回其下的所有子孙节点
@ApiOperation("根据id获取所有子节点")
@GetMapping("/getSons")
public CommonResult<List<String>> getSons( @RequestParam(required = true) String pid){
//存储查询的结果集
List<String> rList = new ArrayList<>();
//清空递归存储器
this.allSons.clear();
//调用递归方法
List<SysChannel> channels= sysChannelService.list();
rList = getAllSons(channels,pid);
return CommonResult.success(rList);
}
基于多个id 获取其子孙以及本身结果集: 如:传入[parentId1,parentId2..] 得到:[parentId1,parentId2..]以及其每个panrentId子孙的合集
@ApiOperation("获取listIds以及其子孙合集")
@GetMapping("/getSonsByIds")
public CommonResult<List<String>> getSonsByIds( @RequestParam(required = true) List<String> ids){
List<String> allIds = new ArrayList<>();
List<SysChannel> channels= sysChannelService.list();
for(String id:ids){
//把传入的id 放置结果集
if(!allIds.contains(id)){
allIds.add(id);
}
//临时list存储 存储每个ids->id下的子节点
List<String> tempIds = new ArrayList<>();
//每次调用递归钱清除存储器
this.allSons.clear();
//递归获取当前id下所有子孙节点
tempIds = getAllSons(channels,id);
//子孙节点不为空的处理
if(tempIds.size()>0){
//循环子孙id结果集
for(String tempId:tempIds){
//结果集不包含当前子孙id 存储结果集
if(!allIds.contains(tempId)){
allIds.add(tempId);
}
}
}
}
return CommonResult.success(allIds);
}