无限级分类设计

无限级分类设计

  • 前言
             无限级分类其实在很多项目中需要应用,例如一些企业部门的分级,区域划分及至商品类别的划分等,数据之间是分等级存在的.结构如下
    area name                       LEVEL 
    中国                               
    1
      华南地区                     
    2
                  广州                 
    3    
                  广西                 
    3
         华东地区                     
    2
    美国                               
    1
         北美                          
    2
         南美                          
    2

    C/S开发中有很方便快捷的控件支持可以快速开发,然而在web 应用中总需要我们进行大量的设计及编码.本文以区域(area)为例介绍web app中无限级分类设计。

    主要设计思考:
    A  DAO层返回分层次的 area  数据 
    B  jsp接收翻译为XML格式化文件
    C  js DOM 操作格式化
    D  HTC接收格式化后的html
    E  控制绑定上HTC,响应onclick事件,进行操作
    效果图如下:

    areatree.gif

    说明:本设计涉及到业务逻辑以及view层的设计
    oracle sql 在分等级的查询中做到了很好的支持,关于oracle中的分等级查询使用,如下
The START  WITH  . . . CONNECT  BY  clause

The PRIOR operator

The 
LEVEL  pseudocolumn

笔者另一篇未完BLOG:
            齐来学习oracle Mastering Oracle SQL 之 Hierarchical Queries/分等级的查询
将会介绍到 : )
  • 业务逻辑
    1、进行多级分类,传统比较笨的办法就是建立N多的表进行关联,
          例如:
          (国家)country  1-*  (省份)province 1-* (市)city …………等等
          然而这样就属于有限分级,每增加一个级别都要增加相关的表及修改N多源码.
          再者区域划分并不是国家,省份,市这样简单的划分能说明问题的。
    2、更优的设计 - 自己关联自己
          area _no                     <-|
          code                              
    |
          name                             
    |
          father_area_no 
    ---------|
          
          每个area都有一个father_area_no字段,关联到其所属区域,如无可为0或null
      然后使用oracle的超级等级查询sql

    select  t. * level   from  area t
     
    start  with  t.father_area_no  is   null             
     connect 
    by  prior t.area_no  =  t.father_area_no    //关系
     
    order  SIBLINGS  by  area_no                            //排序
    //////////////////////////////////////////////////////////////////////////////////////////////////
      AREA_NO CODE                 NAME            PARENT_ID      LEVEL
    ---------- -------------------- -------------- ---------- ----------
           1 A0001                中国                              1
           2 A0002                华南地区                      1                       2
           3 A0002-1              广东                            1                        3
           4 A0002-2              广西                            2                       3
           5 A0002-3              福建                            2                       3
           6 A0002-4              还是不知道的            2                        3
           7 A0003                华东地区                     1                        2

    3、hibernate3原生sql的支持
         public  List getGoodsCatalogTree()
        
    {
            String treeSql 
    = "select {t.*}, level from area t  " +
                    
    " start with t.parent_catalog_no is null " +
                    
    " connect by prior t.goods_catalog_no = t.parent_catalog_no " +
                    
    " order SIBLINGS by goods_catalog_no";

            
    return getSession().createSQLQuery(treeSql)
                    .addEntity(
    "t", GoodsCatalog.class)
                    .addScalar(
    "level", Hibernate.INTEGER).setParameter(0,"A:valid").list();
        }

  • VIEW层设计
    说明,本文hibernate为演示

    1、tree.jsp 接收 hibernate 返回的list并翻译为XML格式 
         效果如下:
      <? xml version="1.0" encoding="GBK"  ?>  
    < tree >
      
    < tree  text ="根类别"  sId =""  action ="selectThis(this)"   />  
    < tree  text ="中国"  sId ="221"  action ="selectThis(this)" >
    < tree  text ="华南地区"  sId ="222"  action ="selectThis(this)" >
      
    < tree  text ="广东"  sId ="242"  action ="selectThis(this)"   />  
      
    < tree  text ="广西"  sId ="244"  action ="selectThis(this)"   />  
      
    < tree  text ="福建"  sId ="245"  action ="selectThis(this)"   />  
      
    < tree  text ="还是不知道的"  sId ="247"  action ="selectThis(this)"   />  
      
    </ tree >
    < tree  text ="华东地区"  sId ="241"  action ="selectThis(this)" >
       </ tree >
      
    </ tree >
      
    </ tree >
    BTW:   关于如何实现,可参考笔者另一篇文章:
      http://www.blogjava.net/davidxu/archive/2005/08/18/10424.html

    2、js DOM解析(笔者使用的是http://webfx.eae.net/ 提供的树)

         pretree.gif
    3、htc 编写,作为js DOM 解析后容器 
          有关于htc更详细的资料请参考相关教程,如你觉得HTC并不适合,可以自己再做相关的封装实现一样的效果.
    //初始化
    <PUBLIC:ATTACH EVENT="ondocumentready" ONEVENT="InitElement()" />
      // 响应onclick事件
    < PUBLIC:ATTACH EVENT = " onclick "  ONEVENT = " keyDownElement() "   />

    ………………
    ………………
    //
    function InitElement()
    {
     var IFRAMEsrc = "<IFRAME border=0 id='multisortTreediv' src='"+ datapage +"'></IFRAME>";
     element.document.body.insertAdjacentHTML("AfterBegin",IFRAMEsrc);
    }
    function keyDownElement()
    {
        //显示隐藏层
    }


    4、area编辑页面中的所属区域控件的调用
      < input type = " text "   class = " text "  id = " areaName "  
                                   
    objectId = " fatherAreaNo "   
                                    name
    = " fatherArea.name "   size = " 48 "  
                                    datapage
    = " /multi-sortTree.jsp?page=/setup/area.do?msg=getAreaTree "  
                                    style = " behavior:url(/js/multi-sortTree.htc); "  value = " " >
                       
    < input type = " hidden "  name = " fatherArea.areaNo "  id = " fatherAreaNo "  value = " " >

    后注:本文只是一种设计思想的介绍,并不提供源码:)
    (本文完! )

你可能感兴趣的:(无限级分类设计)