2011-03-17 51 views
1

請問如何在Grails域類上做投影?就我而言,我想通過他們的ID獲得(例如)用戶名的列表。這意味着在我的方法中,我傳遞了一個userId列表並獲取用戶名稱列表。 Groovy域的動態方法是否支持此功能?目前,我正在使用以下功能:Grails中的投影

public String getUserNamesByIds(String[] ids) { 
    StringBuffer names = User.get(Integer.parseInt(ids[0]).getName()) 
    if(ids.length > 1) { 
     (1..ids.length - 1).each{ 
      names.append(", " + User.get(Integer.parseInt(ids[it])).getName()) 
     } 
    } 
    return names.toString() 
} 

正如您所看到的,我只想獲取名稱(並構建總字符串)。我認爲這不好,因爲我必須做很多小的步驟,並執行許多查詢來獲取用戶對象的數據庫。有沒有更好的方法來做到這一點? 非常感謝!

回答

7

您可以使用一個標準,並與預測,以獲得用戶的名字給它的ID,做這樣的事情:

public List getUserNamesByIds(String[] ids) { 
    def criteria = User.createCriteria() 
    return criteria.list { 
     projections { 
     property("name") 
     } 
     'in'("id", ids) 
    } 
} 

然後,你可以通過做用戶名的列表轉換成一個字符串:

List users = getUserNamesByIds(...) 
String concatenatedNames = (users ? users.join(",") : "") 

您可以在閱讀更多關於指標分析和預測,在這裏。

+0

非常感謝!但是,你能幫助我如何在許多屬性上使用投影嗎?我找不到任何樣品可供參考。再次感謝! – 2011-03-18 10:27:02

+0

我只使用了一個屬性的投影,但我認爲可以添加多個屬性,您可以嘗試一下,看看會發生什麼:-)另外,請檢查此線程以查看是否可以幫助您http:// stackoverflow的.com /問題/ 3720060 /使用-groupproperty和 - countdistinct合的grails-標準 – Maricel 2011-03-18 16:16:00

0

這是一個可怕的想法。原因是每次調用User.get(id)都會通過網絡上的線路進行呼叫。這非常昂貴,即使您的數據庫在20 ms內響應,其中1000個會花費20秒 - 您的用戶需要等待很長時間。更好的辦法是通過某種查詢來獲得您感興趣的用戶集合,然後在內存中對它們進行迭代。每個循環調用需要1 ns或更少的時間。

這個實現是字面上的最大原因,Web應用程序是一個緩慢...

+0

因此,對於我從查詢中提取的用戶集,我可以在該集上執行投影以獲取所有名稱,而不是通過循環遍歷該集來獲取每個名稱?謝謝! – 2011-03-17 18:05:05

+0

您可以循環瀏覽,如果它在內存中並且尺寸較小,那麼這很好。如果您必須爲每個Web請求執行此操作,那麼該操作很糟糕,但是如果您在爲所有用戶執行的計劃作業中執行此操作,並且不會在應用程序運行時影響應用程序的性能。 – 2011-03-17 19:55:10