All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jladder.data.TreeModel Maven / Gradle / Ivy

package com.jladder.data;


import com.jladder.db.DaoSeesion;
import com.jladder.db.IDao;
import com.jladder.db.SqlText;
import com.jladder.lang.Strings;
import com.jladder.lang.func.Action1;
import com.jladder.lang.func.Func2;

import java.util.ArrayList;
import java.util.List;

/// 
/// 树型数据模型
/// 
public class TreeModel
{
    /// 
    /// 现场的记录集
    /// 
    private List rs;

    public List getRs() {
        return rs;
    }

    public void setRs(List rs) {
        this.rs = rs;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getPid() {
        return pid;
    }

    public void setPid(String pid) {
        this.pid = pid;
    }

    public boolean isSerialize() {
        return serialize;
    }

    public void setSerialize(boolean serialize) {
        this.serialize = serialize;
    }

    public Action1 getCallback() {
        return Callback;
    }

    public void setCallback(Action1 callback) {
        Callback = callback;
    }

    /// 
    /// 本字段属性名
    /// 
    private String id = "id";
    /// 
    /// 父字段属性名
    /// 
    private String pid = "pid";
    /// 
    /// 是否进行序列化
    /// 
    private boolean serialize  = true;
    /// 
    /// 回调委托
    /// 
    private Action1 Callback;
    /// 
    /// 散落自由的节点,其ID属性值的集合
    /// 
    private List _deletes=new ArrayList();
    /// 
    /// 用于递归循环的变量储存
    /// 
    private List _ids = new ArrayList();
    /// 
    /// id的映射表
    /// 
    private Record _idmap = new Record();
    /// 
    ///
    /// 
    public TreeModel(){}
    /// 
    ///
    /// 
    /// 
    public TreeModel(List rs)
    {
        this.rs = rs;
    }
    /// 
    /// 获取整体集合
    /// 
    /// 
    public Record GetMap()
    {
        return _idmap;
    }
    /// 
    /// 获取ID序列键的集合
    /// 
    /// 
    public List GetIds(){return _ids;}
    /// 
    /// 删除多余的分支
    /// 
    /// 
    public List GetDeletess() { return _deletes; }
    /// 
    /// 获取一个的节点
    /// 
    /// 节点的id属性值
    /// 
    public Record GetNode(String id)
    {
        return _idmap.containsKey(id) ? (Record) _idmap.get(id) : null;
    }
    /// 
    /// 清理ID的缓存
    /// 
    public void ClearIds(){_ids.clear();}

    /// 
    /// 重置树模型
    /// 
    public void Reset()
    {
        this.rs = null;
        _idmap=new Record();
        this.id="id";
        this.pid="pid";
        this.serialize=true;
        Callback = null;
        _deletes=new ArrayList ();
        _ids = new ArrayList();
    }
    /// 
    /// 执行数据树结构处理,把rs数据记录变成tree数据结构
    /// 
    public void HandleData(){
        if(this.rs==null)return;
        if(Strings.isBlank(this.id)) this.id = "id";
        if(Strings.isBlank(this.pid)) this.pid = "pid";
        if(_idmap==null)_idmap=new Record();//list->map,转化以ID为key,实际输出集合
        //List deletes=new List ();//后续要删除的IDs
        for(Record map : rs){
            String pid=map.getString(this.pid);//取记录集的pid
            String id = map.getString(this.id);//取记录集的id
            //处理父级对象
            if(!Strings.isBlank(pid) && !pid.equals("0")){ //记录存在pid
                if(_idmap.get(pid)==null){//集合中不存在,新建一个,并push该条记录
                    Record pmap=new Record();
                    List plist=new ArrayList();
                    plist.add(map);//map本对象,TMD是浅拷贝,大善
                    pmap.put("children",plist);//push本对象
                    _idmap.put(pid, pmap);
                }else{
                    Record pmap =(Record)_idmap.get(pid);
                    Record newMap = map;
                    List children= (List)pmap.get("children");
                    children.add(newMap);
                    pmap.put("children",children);
                    _idmap.put(pid,pmap);
                }
                _deletes.add(id);
            }
            //处理本对象
            if(_idmap.get(id)==null){
                if (Callback != null)
                {
                    try{
                        Callback.invoke(map);
                    }catch (Exception e){

                    }


                }
                map.put("children",new ArrayList());//先置一个空的children
                _idmap.put(id,map);
            }else{ //已经建立,只更新信息段,children部分保留
                map.put("children", ((Record) _idmap.get(id)).get("children"));//取已经push的children
                if (Callback != null)
                {
                    try{
                        Callback.invoke(map);
                    }catch (Exception e){

                    }
                }
                _idmap.put(id,map);
            }
        }
    }
    /// 
    /// 匹配树的节点,注意列表多个数据,范围树形逐渐缩小
    /// 
    /// 匹配的数据列表
    public void Match(List matchrs)
    {

        if (matchrs == null || matchrs.size()<1) return;
        Record newidsmap=new Record();
        for (Record rs : matchrs)
        {
            String matchid = rs.getString(this.id);
            if (_idmap.containsKey(matchid))
            {
                newidsmap.put(matchid, _idmap.get(matchid));
            }
        }
        _idmap = newidsmap;
    }
    /// 
    /// 删除散落的节点
    /// 
    public void DeleteFreeChild(){
        for(String key : _deletes)_idmap.remove(key);//删除子级Map
        _deletes.clear();
    }
    /// 
    /// 按原记录顺序进行排列并整理成记录集
    /// 
    /// 
    public List OrderByRaw()
    {
        if (this.rs == null) return null;
        List ret = new ArrayList();

        for(Record m : this.rs){
            String _id = m.getString(this.id);
            if(Strings.hasValue(id)&& _idmap.containsKey(_id)){
                ret.add(m);
            }
        }
        return ret;
    }
    /// 
    /// 把树形结构转换成记录集结构
    /// 
    /// 
    public List ConvertToRs()
    {
        List ret = new ArrayList();
        _idmap.forEach((k,y)->{
            ret.add((Record)y);
        });
        return ret;
    }
    /// 
    /// 转换成键值数据结构
    /// 
    /// 键名
    /// 值名
    /// 是否全部数据结构
    /// 
    public Record ConvertTokeyValue(String keyName, String valueName,boolean isAll)
    {
        Record record = new Record();
        _idmap.forEach((k,v) -> record.merge(((Record)v).getKeyValue(keyName, valueName, isAll)));
        return record;
    }
    /// 
    /// 获取键值数据结构
    /// 
    /// 数据
    /// 键名
    /// 值名
    /// 是否全部数据结构
    /// 键值集合
    /// 子数据键名
    /// 
    public static Record getKeyValue(Record data, String keyName, String valueName,boolean isAll, Record kv,String childrenName)
    {
        if(kv==null) kv=new Record();
        List children = (List)data.get(childrenName);
        if (children !=null && children.size() > 0)
        {
            Record record = new Record();
            children.forEach(x -> getKeyValue(x, keyName, valueName, isAll, record,"children"));
            if (isAll || record.size()>0)
                kv.put(data.getString(keyName), record);
        }
            else
        {
            if (isAll || data.containsKey(valueName))
                kv.put(data.getString(keyName), data.get(valueName));
        }
        return kv;
    }

    /// 
    /// 挂载tree,用于两个tree模型的挂载,ischild=true,是挂载两个idmaps的children
    /// 
    /// 树模型数据
    /// 是否子节点挂接
    public void Mount(Record map, Boolean isChild){

        map.forEach((k,v)->{
            Record vmap = (Record)v;
            if (_idmap.containsKey(k))
            {
                Record oldMap =(Record)_idmap.get(k);
                List oldlist = (List)oldMap.get("children");
                if(isChild){
                    List list =(List) vmap.get("children");
                    oldlist.addAll(list);
                    oldMap.put("children", oldlist);
                    _idmap.put(k,oldMap);
                }
            }
        });
    }
    /// 
    /// 追加子记录集
    /// 
    /// 子记录集
    public void PushBatch(List childes)
    {
        if (childes == null || childes.size() < 1) return;
        for(Record node : childes){
            PushChildren((String)node.get(this.pid),node);
        }
    }
    /// 
    /// 追加子节点
    /// 
    /// 节点的上级标识值
    /// 节点数据
    public void PushChildren(String pid, Record node)
    {
        Record oldMap = (Record)_idmap.get(pid);
        if (oldMap == null) return;
        List children = (List)oldMap.get("children");
        if (children == null) children = new ArrayList();
        children.add(node);
        oldMap.put("children", children);
        _idmap.put(pid, oldMap);
    }
    /// 
    /// 获取某节点及下级ID的值
    /// 
    /// 节点
    public List FetchTreeAttribute(Record node){
        List ps = new ArrayList();
        FetchTreeAttribute(ps,node, this.id,null);
        return ps;
    }
    /// 
    /// 获取某节点及下级ID的值
    /// 
    /// 节点
    /// 过滤委托
    /// 
    public List FetchTreeAttribute(Record node, Func2 fun)
    {
        List ps = new ArrayList();
        FetchTreeAttribute(ps,node, this.id, fun);
        return ps;
    }
    /// 
    ///  获取某节点及下级某个属性的值
    /// 
    /// 节点
    /// 属性
    /// 
    public List FetchTreeAttribute(Record node,String propName)
    {
        List  ps=new ArrayList();
        FetchTreeAttribute(ps,node,propName, null);
        return ps;
    }
    /// 
    /// 获取某节点及下级某些属性的值
    /// 
    /// 填充对象
    /// 节点记录
    /// 过滤委托
    /// 属性数组
    public void FetchTreeAttribute(List reList, Record record, Func2 fun, String ... propnames)
    {
        if (reList == null) return;
        if(record==null)return;
        if(propnames == null|| propnames.length==0) propnames =new String[] {this.id};
        Record precord=new Record();
        for (String panme : propnames)
        {
            if (fun == null) precord.put(panme, record.get(panme));
            else
            {
                try {
                    if (fun.invoke(record)) precord.put(panme, record.get(panme));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        reList.add(precord);
        List children = (List)record.get("children");
        for (Record re : children)
        {
            FetchTreeAttribute(reList,re, fun, propnames);
        }
    }
    /// 
    /// 获取某节点及下级某个属性的值
    /// 
    /// 填充对象
    /// 节点记录
    /// 属性名
    /// 过滤委托
    public void FetchTreeAttribute(List reList, Record record, String propname, Func2 fun)
    {
        if (reList == null) return;
        if (record == null) return;
        if (Strings.isBlank(propname)) propname = this.id;
        if (fun == null) reList.add(record.getString(propname));
        else
        {
            try {
                if (fun.invoke(record)) reList.add(record.getString(propname));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        List children = (List)record.get("children");
        for (Record re : children)
        {
            FetchTreeAttribute(reList, re, propname, fun);
        }
    }


    /**  以下代码是进行数据库级别的递归推理过程******/

    /// 
    /// 从表递归
    /// 
    /// pid的值
    /// 表名
    /// 子字段名
    public void RecurFromTable(String pidval, String tableName, String cFieldName)
    {
        RecurFromTable(pidval, tableName, cFieldName, this.pid, DaoSeesion.GetDao());
    }
    /// 
    /// 从表递归
    /// 
    /// pid的值
    /// 表名
    public void RecurFromTable(String pidval, String tableName)
    {
        RecurFromTable(pidval, tableName, this.id,this.pid, DaoSeesion.GetDao());
    }
    /// 
    /// 从表格递归
    /// 
    /// pid值
    /// 表名
    /// id的字段名
    /// pid的字段名
    /// 数据库操作对象
    public void RecurFromTable(String pidval, String tableName, String cFieldName, String pFieldName, IDao dao)
    {
        if (dao == null) dao = DaoSeesion.GetDao();
        if (Strings.isBlank(cFieldName)) cFieldName = "id";
        if (Strings.isBlank(pFieldName)) pFieldName = "pid";
        tableName = Strings.mapping(tableName);
        String sqlcmd = "select " + cFieldName + " from " + tableName + " where " + pFieldName + "='" + pidval + "'";
        List rs = dao.query(new SqlText(sqlcmd));
        if (rs == null || rs.size() < 1) return;
        for (Record record : rs)
        {
            String tid = record.getString(cFieldName);
            _ids.add(tid);
            RecurFromTable(tid, tableName,cFieldName, pFieldName, dao);
        }
    }

    /// 
    /// 递归导出下级的所有IDS(数据库层级)
    /// 
    /// 数据库操作对象
    /// 数据库表名
    /// 父节点值
    /// 子节点字段名称
    /// 父节点字段名称
    /// 

    public static List RecurFromTable(IDao dao, String tableName, String pidval, String cFieldName,String pFiledName)
    {
        if (Strings.isBlank(cFieldName)) cFieldName = "id";
        if (Strings.isBlank(pFiledName)) pFiledName = "pid";
        TreeModel tm = new TreeModel();//Tree数据模型
        tm.RecurFromTable(pidval, tableName, cFieldName, pFiledName, dao);
        List ids = tm.GetIds();
        return ids;
    }



}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy