
Древовидные данные в Grails
В красивой коробке с Grails одако не находится таких полезных аксессуаров, как некое подобие NestedSet
В таких нечеловеческих условиях пытался сделать что-нибудь подобное. И вот к каким выводам пришел:
Нестедсет в Grails на фиг не нужен. Вполне достаточно иметь Domain object со ссылками сам на себя (parent-child relations). А когда возникает вопрос выборок, не мучать мозг, а использовать вещи, изначально пригодные для выборки ancestors, descendants и прочего. Да, я в очередной раз рекламирую XML и XPath.
Суть — получить экземпляр того же EhCache или OsCache в Grails проблемы никакой не составляет. По мере потребности выгружаем структуру, описывающую иерархию объектов в дереве в этот самый кэш в виде dom.Document или даже в виде класса, содержащего сам документ и инструменты выборок по нему. По мере обновления данных этот документ обновляем и в кеше.
Ну а сам Domain выглядить примерно так:
public class Doc {
String name
static belongsTo = [parent:Doc]
static hasMany = [childrn:Doc]
static constraints = {
parent(nullable:true)
name(maxSize:100)
}
}
Тут важно, чтобы parent был nullable, а то объекты первого уровня иерархии будет создать невозможно
ну и тестовое использование:
def d1 = new Doc(name:"lalala 1")
def ch1 = new Doc(name:"child 1")
def ch2 = new Doc(name:"child 2")
def ch3 = new Doc(name:"child 3")
d1.addToChildrn(ch1)
d1.addToChildrn(ch2)
d1.addToChildrn(ch3)
d1.save()
def cc1 = new Doc(name:"grandchild 1")
def cc2 = new Doc(name:"grandchild 2")
def cc3 = new Doc(name:"grandchild 3")
def cc4 = new Doc(name:"grandchild 4")
ch2.addToChildrn(cc1)
ch2.addToChildrn(cc2)
ch2.addToChildrn(cc3)
ch2.addToChildrn(cc4)
ch2.save()
def d = Doc.get(8)
render d.parent?.parent?.childrn.each {
render it.name+"<br/>"
}
Как-то так...
Комментарии (0)