無限級分類設計
- 前言
無限級分類其實在很多項目中需要應用,例如一些企業部門的分級,區域劃分及至商品類別的劃分等,數據之間是分等級存在的.結構如下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事件,進行操作
效果圖如下:
說明:本設計涉及到業務邏輯以及view層的設計
oracle sql 在分等級的查詢中做到了很好的支持,關于oracle中的分等級查詢使用,如下






筆者另一篇未完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>
http://www.aygfsteel.com/davidxu/archive/2005/08/18/10424.html
2、js DOM解析(筆者使用的是http://webfx.eae.net/ 提供的樹)
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="">
后注:本文只是一種設計思想的介紹,并不提供源碼:)
(本文完! )