2012-01-10 86 views
13

我有這樣的代碼,最好的方法:Grails的迭代域類的所有ID

Book.list().each { 
    // real code actually does something more useful 
    println "My id is " + it.id 
} 

這令我有點浪費,每個整本書的對象被加載剛剛訪問ID。在Grails中有一個load()方法,當你只想在ID上操作時,我想知道是否有加載所有域實例的等價物?我應該使用HQL嗎?或者我應該保持現狀?

PS:這讓我不知道是否應該提供給最GORM方法(查找器等),這導致其只是「負荷」,而不是選擇「獲取」目標類

回答

8

您可以使用HQL只返回領域需要

Book.executeQuery("select b.id from Book b");

+0

爲了便於閱讀,我會說使用'namedQueries'或條件查詢比SQL好得多,尤其是在查詢變得更加複雜時。 – 2015-08-27 19:50:41

-2

除非Book對象包含大量的數據,我只是用Book.list去保持簡單。

請記住,加載()實際上沒有命中數據庫,它只是構造一個id集合的對象。

+0

我剛剛嘗試加載,它似乎是擊中數據庫,如果您嘗試訪問除id以外的任何屬性。 – aldrin 2012-01-10 13:04:18

+0

是的,這就是使用.load代替原來的Book(id:2)的原因,它創建了一個代理對象,它在訪問時延遲加載對象。 – 2012-01-10 13:41:46

+0

我同意如果Book類沒有很多數據(小於100k)使用Book.list()可能沒問題。 – 2012-01-10 14:17:55

9

組合條件查詢與當你要避免使用HQL投影解決您的問題。

def criteria = Book.createCriteria() 
    def result = criteria.list { 
     projections { 
      property 'id' 
     } 
    } 

Hibernate的SQL日誌顯示,只有ID被從數據庫加載,而不是整個書籍:select this_.id as y0_ from book this_

標準查詢還可以添加爲Book域類中的named query,從而可以輕鬆訪問標識列表。

5

+1 @魯本的答案,但你可以縮短它簡單地

def criteria = Book.withCriteria { 
    projections { 
     property 'id' 
    } 
} 

,並得到了相同的結果!