mybatis的XML写list参数的处理

99 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

这个前面主要在描述代码场景,您要是脾气暴躁 比较着急,请直接看最后一段代码区!

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);
    }