mybatis递归查询所有子节点总结
2018年04月01日 16:58:23 MeKane 阅读数:459
查找所有资讯种类,并将他们映射到对应节点中,然后找出子节点,返给前端。
数据库结构:
NewsType:
public class NewsType{ private String TypeId; private String ParentId; private String TypeName; private String State; private String SortNum; private String parentTypeName; public String getTypeId() { return TypeId; } public void setTypeId(String typeId) { TypeId = typeId; } public String getParentId() { return ParentId; } public void setParentId(String parentId) { ParentId = parentId; } public String getTypeName() { return TypeName; } public void setTypeName(String typeName) { TypeName = typeName; } public String getState() { return State; } public void setState(String state) { State = state; } public String getSortNum() { return SortNum; } public void setSortNum(String sortNum) { SortNum = sortNum; } public String getParentTypeName() { return parentTypeName; } public void setParentTypeName(String parentTypeName) { this.parentTypeName = parentTypeName; } }
NewsTypeCustom:
public class NewsTypeCustom extends NewsType{ private List<NewsTypeCustom> children; public List<NewsTypeCustom> getChildren() { return children; } public void setChildren(List<NewsTypeCustom> children) { this.children = children; } }
xml文件中,如下代码所示 :
<!-- start 查找所有资讯种类,并将他们映射到对应节点中 --> <select id="findAllRecursion" resultMap="recursionNewsTypeMap"> SELECT * FROM tblnewstype WHERE ParentId ='' or ParentId is NULL ORDER BY `SortNum` ASC </select> <select id="findNewsByParentId" resultMap="recursionNewsTypeMap"> SELECT * FROM tblnewstype WHERE ParentId = #{TypeId} ORDER BY `SortNum` ASC </select> <resultMap id="recursionNewsTypeMap" type="NewsTypeCustom"> <id column="TypeId" property="TypeId"/> <result column="ParentId" property="ParentId"/> <result column="TypeName" property="TypeName"/> <result column="State" property="State"/> <result column="SortNum" property="SortNum"/> <collection property="children" ofType="NewsTypeCustom" column="TypeId" select="findNewsByParentId"> </collection> </resultMap> <!-- end 查找所有资讯种类,并将他们映射到对应节点中 -->
注:
特别注意递归,要两个select标签都是这一个resultmap,第一个是查找根节点,第二个是递归查找节点 。
serviceimpl中,如下代码所示 :
@Override public List<NewsTypeCustom> findAllLeafNewsTypes() { List<NewsTypeCustom> newsTypesList = null; List<NewsTypeCustom> finalNewsTypesList = new ArrayList<>(); List<NewsTypeCustom> newsTypesTree = appNewsMapper.findAllRecursion(); for (NewsTypeCustom newsTypeCustom:newsTypesTree) { System.out.println("One Traversal"); if(newsTypeCustom.getParentId() == null || newsTypeCustom.getParentId() == "") { System.out.println("newsTypeRootNode:" + newsTypeCustom.toString()); newsTypesList = getLeafNode(newsTypeCustom.getChildren()); } for (NewsTypeCustom finalnewsTypeCustom:newsTypesList) { finalNewsTypesList.add(finalnewsTypeCustom); } } return finalNewsTypesList; }
/** * 获取资讯父节点下面的所有子节点 * @param NewsTypeCustomList * @return List<NewsTypeCustom> */ public static List<NewsTypeCustom> getLeafNode( List<NewsTypeCustom> NewsTypeCustomList){ List<NewsTypeCustom> newsTypeLeafNode = new ArrayList<>(); for(NewsTypeCustom newsTypeCustom: NewsTypeCustomList){ System.out.println("One ChildTraversal:"+newsTypeCustom.toString()); //子节点为空的话,add进叶子节点集合 if(newsTypeCustom.getChildren().size() != 0){ System.out.println("newsTypeCustom.getChildren()!!!!!"+newsTypeCustom.getChildren()); newsTypeLeafNode.addAll(getLeafNode(newsTypeCustom.getChildren())); }else{ //递归遍历下一级 newsTypeLeafNode.add(newsTypeCustom); } } return newsTypeLeafNode; }
注:
同样,注意在静态方法中的递归,一定要每一次都将得出的子节点加入到newsTypeLeafNode中(我在写的时候忘掉了,发现只有根节点下面的子节点,而没有将孙子等节点纳入集合中 ) 。
newsTypeLeafNode.addAll(getLeafNode(newsTypeCustom.getChildren()));
不要写成:
getLeafNode(newsTypeCustom.getChildren());