我们在项目开发中,经常会遇到存在上下级关系的数据,比如商品类型的级别分类,食品类下分类熟食类和肉食类,肉食类下又分了海鲜类和家禽类,等等诸如此类的数据结构。
以下我将以公司部门的层级结构来为例子,详细介绍Java使用循环来做层级结构化分类数据。
部门实体类
部门实体类的数据库设计是这样的,一个部门有名称、编号,如果该部门没有上级,那么父级ID字段则为空;如果该部门存在上级,那么其父级ID字段则为父级部门的ID。
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class OrganizationFrameInfo extends Model<OrganizationFrameInfo> {
public static final long serialVersionUID = 1L;
public OrganizationFrameInfo(){}
//属性
private Long orgfraId; //主键ID
private String orgfraStrId; //字符主键ID
private String orgfraName; //组织部门名称
private Integer orgfraType; //类型,1为最高级,2为第二级,3为第三级,以此类推...
private String orgfraNo; //部门编号
private String orgfraParentId; //上级组织字符ID
private String addDate;
private Integer stratus;
}
部门Pojo实体类
@JsonInclude(JsonInclude.Include.NON_NULL)
public class OrganizationFrameInfoPojo extends BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
public OrganizationFrameInfoPojo(){}
//属性
private Long orgfraId; //主键ID
private String orgfraStrId; //字符主键ID
private String orgfraName; //组织部门名称
private Integer orgfraType; //类型,1为最高级,2为第二级,3为第三级,以此类推...
private String orgfraNo; //部门编号
private String orgfraParentId; //上级组织字符ID
private String addDate;
private Integer stratus;
//子级部门信息
private List<OrganizationFrameInfoPojo> children;
/***此处省略了属性的Get Set方法,自行补充***/
//将实体类转化为Pojo类的方法
public static OrganizationFrameInfoPojo entityToPojo(OrganizationFrameInfo entity){
OrganizationFrameInfoPojo pojo=new OrganizationFrameInfoPojo();
BeanUtils.copyProperties(entity, pojo);
return pojo;
}
public List<OrganizationFrameInfoPojo> getChildren() {
return children;
}
public void setChildren(List<OrganizationFrameInfoPojo> children) {
this.children = children;
}
}
业务处理数据层级结构化(重点)
以下是将数据层级结构化的方法
/***
* 部门层级分类
* 循环获取字典数据 树
* 子ID必须小于父ID
* 查询所有数据时必须按照ID从小到大排序
* 换而言之就是父级必须在前面
*/
public List<OrganizationFrameInfoPojo> getSelectOrganizationAllList(OrganizationFrameInfoPojo organization) {
//查询所以出数据
List<OrganizationFrameInfo> entityList=organizationFrameInfoMapper.listAll(organization);
//转化为Pojo
List<OrganizationFrameInfoPojo> pojoList=new ArrayList<>();
entityList.forEach(entity ->pojoList.add(OrganizationFrameInfoPojo.entityToPojo(entity)));
//最终输出的树
List<OrganizationFrameInfoPojo> pojoResult=new ArrayList<>();
//以ID为键保存每一条数据
Map<String, OrganizationFrameInfoPojo> map=new HashMap<>();
for(OrganizationFrameInfoPojo pojo:pojoList){
String strId=pojo.getOrgfraParentId();
map.put(pojo.getOrgfraStrId(), pojo);
//如果在map不存在当前数据的父ID为键的数据,则为0,保存在输出树中
if(null==map.get(strId)){
pojoResult.add(pojo);
}else{
//如果在map存在当前数据的父ID为键的数据,则将当前数据加入到父节点的children中
OrganizationFrameInfoPojo one=map.get(strId);
if(null==one.getChildren()){
one.setChildren(new ArrayList<>());
}
one.getChildren().add(pojo);
}
}
return pojoResult;
}