`
liuhanjun
  • 浏览: 47791 次
  • 性别: Icon_minigender_1
  • 来自: 海口
社区版块
存档分类
最新评论

查询树中某节点所有的后代节点

    博客分类:
  • J2EE
阅读更多

在数据库的设计里面,经常使用parentId字段来构建树型的表结构,如部门、知识点等,数据举例:物电学院->自动化系->08自动化->08自动化一班,类似于这样的数据结构。如何查询某个节点下的所有子孙节点,在程序设计中有两种方法。以如下表结构做说明:

CREATE TABLE `basic_depart` (
  `departId` char(32) CHARACTER SET latin1 NOT NULL COMMENT '部门ID',
  `parentId` char(32) CHARACTER SET latin1 DEFAULT NULL COMMENT '父ID',
  `nodeType` tinyint(4) DEFAULT NULL COMMENT '0:无下级;1:有下级',
  `name` varchar(50) DEFAULT NULL COMMENT '部门名称',
  `telephone` varchar(20) DEFAULT NULL COMMENT '联系电话',
  `sortOrder` tinyint(4) DEFAULT NULL COMMENT '排序',
  `remark` varchar(1000) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`departId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

1、写一个递归函数来递归查询

public List<Depart> getDepartTree(String parentId) throws SQLException {
  List<Depart> departList = dao.queryList("depart.getChildDepart", parentId);

  if (departList != null && departList.size() > 0) {
   Iterator<Depart> departIterator = departList.iterator();
   while (departIterator.hasNext()) {
    Depart depart = departIterator.next();
    depart.setSubDepartList(getDepartTree(depart.getDepartId()));
   }
  }

  return departList;
 }

  

递归函数比较简单,记住递归的2个要素:递归结束的条件和递归公式,一般不会有啥问题。

 

2、参考网上一哥们的思路,写一个求出所有子孙节点ID和自己的ID的mysql function

DROP FUNCTION IF EXISTS oes.depart_getChilds;
CREATE FUNCTION oes.`depart_getChilds`(rootId varchar(32)) RETURNS varchar(10000) CHARSET latin1
BEGIN
 DECLARE sTemp VARCHAR(10000);
  DECLARE sTempChd VARCHAR(10000);

  SET sTemp = rootId;
  SET sTempChd = rootId;
   
  WHILE sTempChd is not null DO
    SELECT group_concat(departId) INTO sTempChd FROM basic_depart where FIND_IN_SET(parentId,sTempChd) > 0;
    IF sTempChd is not null THEN 
     SET sTemp = concat(sTemp,',',sTempChd);
    END IF;
  END WHILE;
  RETURN sTemp;

END;

 

然后在程序或者ibatis里面设置查询条件类似下面:

select * from basic_depart where find_in_set(departId,depart_getChilds('root')) 

 

这里稍微说一下,我数据库的全套charset和collation都是UTF8。

 1.depart_getChilds函数RETURNS varchar(10000) CHARSET latin1,为什么要给返回值定义为charset latin1呢,因为貌似find_in_set函数的2个参数要求是latin1编码的(更正:不是find_in_set函数的问题,是departId字段的collation的设置问题)。不如此,就会报incorrect mix of collation的错误,为这个,浪费了我一个下午的时间。

 2.本来我想写一个通用的mysql函数,处理所有树型结构的table,把table的名称,parentId字段名称,Id字段名称通通作为参数传递给getChilds函数。结果天不遂人愿,mysql不支持在function和procedure里面使用动态sql,要命3000

 3.为什么要第2个方法呢,一个是简单,一个是因为做ibatis的sqlmap的时候用得上,比如:

 

<select id="getList" resultMap="questionRM">
  select * from ed_question where parentId is null
  <dynamic prepend="and">
   <isNotEmpty property="question.knowledgeId" prepend="and">
    find_in_set(knowledgeId , knowledge_getChilds(#question.knowledgeId#))
   </isNotEmpty>
   <isNotEmpty property="question.quesTypeId" prepend="and">
    quesTypeId = #question.quesTypeId#
   </isNotEmpty>
   <isNotEmpty property="question.status" prepend="and">
    status = #question.status#
   </isNotEmpty>
   <isNotEmpty property="question.difficulty" prepend="and">
    difficulty = #question.difficulty#
   </isNotEmpty>
   <isNotEmpty property="question.title" prepend="and">
    title like concat('%',#question.title#,'%')
   </isNotEmpty>
  </dynamic>
  order by createTime desc
 </select>

 

1
0
分享到:
评论
2 楼 wangkaizhen 2013-04-09  
我也向您这样做的,但是就是总是出现
Illegal mix of collations (utf8_general_ci,IMPLICIT) and (ucs2_general_ci,IMPLICIT) for operation 'find_in_set'
这个错误。我看了我的表里面全部都是设置的utf8_general_ci类型的。
1 楼 fhl2010 2011-01-27  
ghfghgf[color=red][/color][align=left][/align][size=large][/size]

相关推荐

    根据父节点找所有子节点数据.zip

    在实际应用中,我们需要经常进行树的查询操作,例如查找一个特定节点的所有子节点。本案例提供了一个Java工具类,用于根据父节点递归地查找并返回所有子节点的数据。 首先,我们要理解什么是树查询。在树形结构中,...

    红黑树添加删除节点操作详解资料整理.doc

    5. **对于每个节点,从该节点到其所有后代叶节点的路径上,包含相同数量的黑色节点**,这一属性被称为黑色高度。 红黑树的插入操作: 1. 插入操作首先按照二叉查找树的方式插入新节点,新插入的节点默认设置为红色...

    Oracle通过递归查询父子兄弟节点方法示例

    1. **查询某节点下所有后代节点(包括各级父节点)** 使用以下查询,可以获取ID为101的节点及其所有后代,包括各级父节点: ```sql SELECT t.* FROM SYS_ORG t START WITH id = '101' CONNECT BY parent_id = ...

    JQ 遍历节点树

    在实际应用中,遍历节点树常用于实现如数据绑定、DOM更新、动态内容加载等功能。例如,我们可以遍历整个页面,找到特定类型的元素进行样式修改,或者获取某个元素的所有祖先元素来实现特定的导航效果。 为了更好地...

    jquery遍历节点树

    4. **$(selector).find(selector)**: 这是jQuery中最强大的遍历方法之一,它可以查找匹配子选择器的所有后代节点,无论它们是直接子节点还是更深层的子节点。例如,如果要找到所有`&lt;div&gt;`下的所有`&lt;span&gt;`元素,可以...

    HashMap中红黑树插入节点的调整过程.doc

    5. 对每个节点,从该节点到其所有后代叶子节点的简单路径上,均包含相同数目的黑色节点。 为了保持这些性质,插入节点后需要进行一系列的调整,包括颜色翻转和旋转操作。 二、HashMap源码中红黑树插入节点的调整...

    Oracle树查询总结

    1. **查找树中的所有顶级父节点** 使用 `WHERE parent_id=0` 即可找到树中的顶级父节点,因为顶级节点通常没有父节点,其 `parent_id` 值为 0。 2. **查找一个节点的直属子节点(所有儿子)** 通过 `WHERE parent...

    javascript节点属性和方法

    DOM 将文档看作是一个树形结构,每个节点都是树形结构中的一个元素,可以是元素、属性、文本、注释、CDATA 段等。 在 DOM 中,每个节点都有其自己的属性和方法,通过这些属性和方法,可以控制和操作节点的结构和...

    JS_操作节点.doc

    19. **preserveWhiteSpace**:可读写属性,决定是否保留文本节点中的空白字符。 20. **previousSibling**:只读属性,返回当前节点的前一个兄弟节点。 21. **Text**:返回节点及其后代的文本内容,用于合并所有...

    DOM对象中的节点操作.pdf

    DOM分层概念中,从上至下可以划分为根节点、父节点、子节点、兄弟节点、后代节点和叶子节点。根节点是树状结构的最顶层节点,在HTML文档中对应;父节点指的是在树状结构中比当前节点上一级的节点;子节点则是直接...

    js节点操作

    `Xml` 属性返回当前节点及其所有后代节点的 XML 表示形式。这对于调试和查看节点结构非常有用。 #### 三、核心方法 ##### 1. appendChild 为当前节点添加一个新的子节点,放在最后的子节点后 `appendChild` 方法...

    C# LinqXML遍历指定节点下的所有对象

    为了遍历指定节点下的所有对象,我们可以使用`Descendants()`方法,这个方法返回一个`IEnumerable&lt;XElement&gt;`类型的序列,包含了指定XPath表达式下的所有后代元素。 下面是一个基本示例,展示了如何遍历XML文档中...

    mysql递归调用获取树节点(子树).pdf

    这个方法的核心在于递归调用 `createChildLst`,通过游标遍历所有子节点,再对每个子节点进行同样的处理,直到遍历完所有后代。这样,我们可以获取到一个节点及其所有子孙节点的列表,而且结构清晰,便于进一步分析...

    Oracle树查询实例分析

    使用`WHERE sjflid IS NULL`的查询可以找到树中的所有顶级节点,这些节点没有上级节点,它们是树的起始点。这对于构建目录结构或组织结构图很有用,因为通常我们需要从最顶层开始遍历。 2. **查找直属子节点** ...

    用xpath精确定位节点元素

    所有其他节点都是其子节点或后代节点。在XSLT处理中,对树的匹配通常从根节点开始。 2. **元素节点(ElementNodes)**:元素节点对应于XML文档中的元素。每个元素节点可能包含子元素节点、文本节点、注释节点或处理...

    基于链表节点实现二叉树节点(Java源码)

    //该节点中存放的对象 protected BinTreePosition parent;//父亲 protected BinTreePosition lChild;//左孩子 protected BinTreePosition rChild;//右孩子 protected int size;//后代数目 protected int height...

    sql查询某个parentid下的所有childid

    在数据库管理和应用开发中,经常需要查询某一特定节点下的所有子节点信息。例如,在组织结构、产品分类等层级数据管理中,我们需要获取某个父级分类的所有子分类,包括直接子分类以及其所有的后代分类。本篇文章将...

    详细讲解JS节点知识

    理解DOM中的节点关系是关键,它们形成了一个树形结构,根节点位于顶部,然后是各级子节点。例如,HTML文档的根节点通常是`&lt;html&gt;`,其下有`&lt;head&gt;`和`&lt;body&gt;`作为子节点。通过遍历和操作这些节点,我们可以动态修改...

    从2-3树理解红黑树

    树中的每个节点都包含一个或两个键,且所有键按照升序排列。插入和删除操作在2-3树中保持了其平衡性,这意味着树的高度保持在log base 2(n+1)范围内,其中n是树中的元素数量。这种平衡特性使得2-3树的查找、插入和...

Global site tag (gtag.js) - Google Analytics