java web 无限层级树状数据的增删改

2020-01-31  本文已影响0人  东本三月

1.说明

2.model与数据库

/**
 * 基本角色表
 */
@Data
@TableName(value = "base_role")
public class BaseRole extends BaseModel {

    //角色别名
    @NotEmpty(message = "角色别名不能为空")
    private String code;

    //角色名称
    @NotEmpty(message = "角色名称不能为空")
    private String name;

    //父角色id
    private  Integer parent_id;

    //该角色所有的父角色id集合,数据格式:[0],[2],[152],
    private String parent_ids;

    //该角色的层级,一般与父角色的数量一致
    private Integer level;

    //角色说明
    private  String remark;

}

3. 数据的新增与修改



List<BaseRole> getLikeParentIds(Integer id);
   <select id="getLikeParentIds" resultType="com.****.model.base.BaseRole">
        SELECT a.* FROM base_role a where 1=1
        <if test="id != null and id != ''">
            and parent_ids LIKE CONCAT('%$[',#{id},'$]%') escape '$'
        </if>
    </select>

  /**
     * 设置一个角色的parent_ids属性和level属性
     * @param model
     */
    public void setParentIds(BaseRole model){
        Assert.isTrue(model!=null,BaseExceptionEnum.PARA_ERROR);
        Integer parent_id=model.getParent_id();

        if(model.getParent_id()!=null){
            //如果修改了父角色,验证设置的父对象是否合法,不能将自身的子对象设置为自己的父对象
            if(!ModelUtil.isNew(model)){
                BaseRole oldModel=super.getById(model.getId());
                Assert.isTrue(oldModel!=null,BaseExceptionEnum.PARA_ERROR);
                String old_parent_ids=oldModel.getParent_ids();
                List<BaseRole> roles=roleDao.getLikeParentIds(oldModel.getId());
                for(BaseRole role:roles){
                    Assert.isTrue(!role.getId().equals(model.getParent_id()),"不能将自身的子角色设置为自己的父角色");
                }
            }
            //获取父角色的parent_ids
            //父角色的parent_ids + 父角色的id = 当前角色的parent_ids
            BaseRole parentModel=super.getById(parent_id);
            Assert.isTrue(parentModel!=null,BaseExceptionEnum.PARA_ERROR);
            model.setParent_ids(parentModel.getParent_ids()+"["+model.getParent_id()+"],");

            //设置层级
            //父角色的层级 + 1 = 当前角色的层级
            int level=0;
            if( parentModel.getLevel()!=null){
                level = parentModel.getLevel();
            }
            model.setLevel(level+1);
        }else{
            model.setParent_ids("");
            model.setLevel(1);
        }
    }

/**
     * 在修改后,更新所有子角色的结构
     * @param oldRole
     * @param newRole
     */
    public void updataAllChildParentIdsForEdit(BaseRole oldRole, BaseRole newRole){
        /*
         例子:
         oldRole是 A ,  A的父级是P  ,newRole是 N
         A 有 两个子级 ,是 A1 和 A2
         A2 有个子级是 A21
         * */

        /*
        获取所有的子角色
        相当于获取了 A1,A2,A21 三个对象
        * */
        List<BaseRole> roles=roleDao.getLikeParentIds(oldRole.getId());
        /*
         * 获取所有子级的公共父级元素信息
         * A1,A2,A21三个子级元素都有父级元素 [A],[P],
         * 将A的所有父级加上A本身,就是所有子级的公共父级元素
         * */
        String oldPidsPrefix = oldRole.getParent_ids() + "[" + oldRole.getId() + "],";

        //遍历所有子级对象
        for(BaseRole role:roles){
            //更新当前子角色的所有父级元素信息
            /*
            获取当前角色的非公共得到父级元素信息
            A21除了有公共的[A],[P],父级外,还有一个父级[A2]
            角色的所有父级信息是按层级顺序排的,截去前面的公共父级,后面的就是非公共父级元素信息
            * */
            String oldPidsSuffix = role.getParent_ids().substring(oldPidsPrefix.length());
            /*
            创建当前子角色新的父级元素信息
            N的所有父级元素 + N本身 +当前角色非公共父级元素信息 = 新的所有父级元素信息
            * */
            String role_parent_ids = newRole.getParent_ids() + "[" + newRole.getId() + "]," + oldPidsSuffix;

            role.setParent_ids(role_parent_ids);
            //更新层级数,角色的父级元素数量+1
            int level = StrUtil.count(role_parent_ids, "[");
            role.setLevel(level);
            super.updateById(role);
        }
    }

/**
     * 添加或编辑
     * @param model
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public void addOrEdit(BaseRole model) {
        Assert.isTrue(super.isUnique(model,"code"),"角色别名不能重复");
        Assert.isTrue(super.isUnique(model,"name"),"角色名称不能重复");
        
        //设置 parent_ids属性值和 level属性值
        setParentIds(model);

        //新增的数据直接保存
        if(ModelUtil.isNew(model)){
            super.saveOrUpdate(model);
        }else{
            //在进行修改时,更新子角色
            BaseRole oldModel=super.getById(model.getId());
            updataAllChildParentIdsForEdit(oldModel,model);
            //完整更新
            super.updateIntact(model);
        }
    }

4.数据的删除

    /**
     * 删除(不包括子角色)
     * @param ids
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public void delete(Integer[] ids){
        Assert.isTrue(ids!=null, BaseExceptionEnum.PARA_ERROR);
        for(int i=0;i<ids.length;i++){
            Integer id=ids[i];
            BaseRole baseRole=super.getById(id);
            Assert.isTrue(baseRole!=null,BaseExceptionEnum.PARA_ERROR);
            updataAllChildParentIdsForDelete(baseRole);
           super.removeById(id);
        }
    }

    /**
     * 删除,包括子角色
     * @param ids
     */
    @Transactional(rollbackFor=Exception.class)
    @Override
    public void deleteChildren(Integer[] ids){
        Assert.isTrue(ids!=null, BaseExceptionEnum.PARA_ERROR);
        for(int i=0;i<ids.length;i++){
            Integer id=ids[i];
            BaseRole baseRole=super.getById(id);
            Assert.isTrue(baseRole!=null,BaseExceptionEnum.PARA_ERROR);
            deleteAllChild(baseRole);
            super.removeById(id);
        }
    }
  /**
     *在删除后,修改子角色的继承关系和层级
     * @param byDelete 被删除的角色
     */
    public void updataAllChildParentIdsForDelete(BaseRole byDelete){
        List<BaseRole> roles=roleDao.getLikeParentIds(byDelete.getId());
        for(BaseRole role:roles){
            String new_parent_ids=StrUtil.replace(role.getParent_ids(),"["+byDelete.getId()+"]","");
            role.setParent_ids(new_parent_ids);

            role.setParent_id(byDelete.getParent_id());

            role.setLevel(role.getLevel()-1);
            super.updateById(role);
        }
    }

4.数据的查询

上一篇 下一篇

猜你喜欢

热点阅读