神奇的Grails:自關聯的樹狀Domain一行代碼獲取全部子節點

      見證Groovy/Grails的神奇時刻到了,你相信嗎?用一行代碼就能夠獲取樹狀結構中某節點下的全部所有子節點!注意:這個樹是無深度限制的。無深度限制這點很重要,若是有限深度的樹,那咱們也很容易經過層級編碼用「Like 001%」方式實現(維護編碼也是一個有挑戰性活)。咱們以一個很是常見的「類別」Domain爲例,大類分小類,小類再細分,典型的樹形結構,看看Grails是如何以簡潔的語法表達的,體驗Groovy語法的神奇!算法

 

class Group{
    String name

    static hasMany = [children:Group]
    static belongsTo = [parent: Group]

    static transients = ['allChildren']

    def getAllChildren(){
        children ? children + children*.allChildren.flatten() : []
    }
}

 

1.兩行代碼表述一個樹狀結構,同時Grails自動爲你生成數據庫表數據庫

 

static hasMany = [children:Group]
static belongsTo = [parent: Group]

 

2.一行代碼獲取任意深度的所有子節點:數組

children ? children + children*.allChildren.flatten() : []

 

   遞歸調用這個是必須的*. allChildren .flatten()。

   短短一行代碼,展示了五個Grovvy的知識點:編碼

   (1)能夠省略 return 。這對不肯多打一個字母的懶人來講也是不小的福利;spa

   (2)[]。這可不是數組,在Groovy中最多見的列表List;code

   (3)操做符重載:List 的 「 + 」 運算符。assert [1,2,3,4] == [1,2] + [3,4];blog

   (4)*展開元素操做符。自動對List中的每一個元素進行枚舉操做,不用爲此寫一個for循環了;遞歸

   (5)flatten() 。這是實現此算法的關鍵,它將全部遞歸獲得的嵌套子節點List使用flatten操做,rem

獲得一個一維的Group列表。List的這個flatten()方法能做到:get

       assert [1,2,3,4,5] == [1,[2,3],[[4]],[],5].flatten()

 

至此,一個徹底可用的樹狀結構領域模型完成了,你能夠調用Grails的GORM語法糖addToChildren,removeFromChildren 任意的添加/刪除子節點,save,delete這些神奇的GORM方法自不用說,更不用寫Hibernate的XML。

相關文章
相關標籤/搜索