Grails2中的Sets, Lists 和Maps

對象集

默認情況下,當你定義中GORM一個java.util.Set映射,這是一個無序的集合,不能包含重複。換句話說,當你有:

class Author {

    static hasMany = [books: Book]

}

books屬性是GORM注入一個java.util.Set映射。Sets保證唯一性,但沒有秩序,這可能不是你想要的。要自定義排序,你要配置Set,就像下面的SortedSet

class Author {

    SortedSet books

    static hasMany = [books: Book]

}

這裏是一個java.util.SortedSet的實現,它意味着你必須在你的Book class中實現java.lang.Comparable

class Book implements Comparable {

    String title

    Date releaseDate = new Date()

    int compareTo(obj) {

        releaseDate.compareTo(obj.releaseDate)

    }

}

上述類的結果是在Author類的books集合中按照發布日期排序的一個Book實例。

對象列表

爲了保持它們被添加的順序和對象能夠像一個數組按照索引引用它們,你可以定義你的集合類型爲List

class Author {

    List books

    static hasMany = [books: Book]

}

在這種情況下,當你添加新的元素到books集合中,排序是一個從0開始索引的順序列表,你可以這樣做:

author.books[0]// get the first book

其工作原理是Hibernate在數據庫層創建一個叫做books_idx的列用來將集合中的元素的索引順序保存在數據庫層。

當使用List時,在保存之前必須將添加元素到集合中,否則Hibernate會拋出一個的異常(org.hibernate.HibernateException:空索引列的集合):

// This won'twork!

def book = new Book(title: 'The Shining')

book.save()

author.addToBooks(book)

// Do it this way instead.

def book = new Book(title: 'Misery')

author.addToBooks(book)

author.save()

對象包

如果排序和唯一性不用考慮(或者你能明確管理這些)那麼你可以使用 Hibernate Bag 類型來表示映射的集合。

唯一需要改變的是定義集合類型Collection:

class Author {

   Collection books

   static hasMany = [books: Book]

}

由於唯一性和排序由Hibernate管理,從集合中添加或刪除映射爲一個包的,不觸發數據庫中的所有實例的負載,所以這種方式比使用Set或者List將有更好的表現和需要較少的內存。

對象Maps

如果你想要一個簡單的map字符串/值對,GORM可以用下面的映射:

class Author {

    Map books // map of ISBN:book names

}

def a = new Author()

a.books = ["1590597583":"Grails Book"]

a.save()

在這裏map的鍵和值都必須是String類型的。

如果你想 Map 對象,你可以這樣做:

class Book {

    Map authors

    static hasMany = [authors: Author]

}

def a = new Author(name:"Stephen King")

def book = new Book()

book.authors =[stephen:a]

book.save()

靜態的hasMany屬性在Map中定義了元素類型,鍵值必須是字符串

集合類型及其性能

Java Set不允許重複。爲確保唯一性,當添加一個實體到一個Set關聯Hibernate不得不從數據庫加載該實體的關聯。假如你有大量的關聯,那麼在性能方面付出的代價是昂貴的。

List類型也有相同的特性,因爲Hibernate需要加載整個關聯,以維持順序。因此建議,如果你希望關聯大量的記錄,那麼你製作一個雙向關聯,以使鏈接可以創建在反面。例如,考慮下面的代碼:

def book = new Book(title:"New Grails Book")

def author =Author.get(1)

book.author =author

book.save()

在這個例子中,關聯鏈接從孩子(Book)創建,因此它沒有必要去操作集合,使用更少的查詢,代碼更高效。由於Author有大量的關聯的Book實例,如果你要編寫類似下面的代碼,對性能的影響就會加大:

def book = new Book(title:"New Grails Book")

def author =Author.get(1)

author.addToBooks(book)

author.save()

你也可以建立類似Hibernate包的集合模型。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章