領先一步
VMware 提供培訓和認證,助您加速進步。
瞭解更多上週,我描述了 Grails 如何將外掛視為可以從 Maven 相容儲存庫中拉取的普通依賴項。雖然這是 1.3 的一個重要新功能,但並非唯一的功能。在這篇文章中,我將介紹一些其他功能,並從我最近才發現的一個功能開始。
開發一個非瑣碎的 Grails 應用程式,您很快就會意識到您經常重複使用相同的查詢。您應該怎麼做?複製貼上技術很簡單,但會留下重大的維護問題。您可以為每個常用查詢編寫服務方法,但隨後會得到相當精細的服務和相當“愚鈍”的域模型。這些查詢的理想位置是域類本身。
這就是命名查詢的用武之地——這項功能在 Grails 1.2 中悄然出現。
[/caption]基本思想是,一份報告可以涉及一個或多個伺服器,並且可能每月生成一次或多次。所以dow代表“一週中的某一天”,而wom代表“一個月中的第幾周”。每臺伺服器都有一個關聯的位置,在這個大大簡化的模型中,這只是一個城市名稱。
現在考慮一下應用程式可能想從這個模型中提取哪些資訊:也許是本月第一週生成的所有報告,或者是關於特定伺服器的所有報告。我們可以將靜態方法新增到Report類來提供此類查詢,但命名查詢為我們提供了一些額外的優勢,稍後您將看到。
建立命名查詢很簡單,正如您對 Grails 所期望的那樣。只需在相關域類中新增一個靜態的namedQueries屬性,併為其分配一個閉包。
class Report {
String name
static hasMany = [frequencies: Frequency, servers: Server]
static namedQueries = {
inFirstWeek {
frequencies {
eq("wom", 1)
}
}
inWeek { wom ->
frequencies {
eq("wom", wom)
}
}
dilbertsReports {
servers {
eq("mgrEmail", "[email protected]")
}
}
inCity { city ->
servers {
location {
eq("city", city)
}
}
}
}
上面的程式碼設定了四個查詢:inFirstWeek、inWeek、dilbertsReports 和 inCity。然後,您可以在使用動態查詢器的地方使用它們,例如在控制器操作或服務方法中。如果您想檢索在本月第一週生成的所有報告,可以這樣呼叫相關的命名查詢:
Report.inFirstWeek.list()
如果您想檢索本月其他周生成的所有報告,則使用inWeek代替。
Report.inWeek(2).list()
看看您如何向命名查詢傳遞引數?只需確保您的命名查詢閉包聲明瞭適當數量的引數。
希望您能看到宣告和使用命名查詢有多麼容易,但在我繼續之前,有幾點值得澄清。
首先,您必須使用 Grails 的 criteria DSL 編寫查詢。如果您一直在推遲學習 criteria DSL,現在您有一個很好的理由停止拖延!
其次,您可以像呼叫標準 GORM 檢索方法(例如list(), get()find()` 或 `findAll()`)或動態查詢器一樣,透過靜態屬性(如果您不向其傳遞任何引數)或方法來呼叫 DSL。這意味著您可以為命名查詢新增額外的過濾。還值得指出的是,get()`Report.get(reportId)` 將僅在命名查詢的結果包含所需實體時才返回域例項。否則,get()`Report.get(reportId)` 將簡單地返回null.
null。換句話說,假設inFirstWeek查詢返回 ID 為 1、3 和 6 的域例項。那麼
Report.inFirstWeek.get(3)
`Report.get(3)` 將返回 ID 為 3 的域例項,而
Report.inFirstWeek.get(2)
`Report.get(2)` 將返回nullnull,即使Report.get(2)返回一個真實的域例項。因此,命名查詢充當過濾器。
到目前為止,一切都很好。命名查詢與get(), list()`find()` 和 `findAll()` 以及動態查詢器結合使用的方式,可能足以立即使用它們。但 Grails 1.3 還藏著另一個絕招。
Report.dilbertsReports.inFirstWeek.list()
`Report.dilbertsReports().inFirstWeek()`。或者,如果您想獲取倫敦伺服器的任何第一週報告,您可以使用
Report.inFirstWeek.inCity("London").list()
`Report.inFirstWeek().inCity('London')`。事實上,只要它們都返回相同型別的域類,您就可以連結任意數量的命名查詢。
命名查詢提供了一種強大的查詢重用技術,該技術實現簡單且易於使用。現在,您可以擁有一個非常豐富的域模型,並且客戶端程式碼易於閱讀和理解。這有多好?
現在我想快速看一下 Grails 1.3 的其他一些功能。
def book = Book.get(10)
assert !book.dirty
book.title = "Unknown"
assert book.dirty
assert book.isDirty("title")
assert !book.isDirty("author")
方法訪問此功能。看看您還可以檢查單個欄位是否已被修改?
grails.sitemesh.default.layout = 'defaultLayout'
`grails-app/views/layouts/application.gsp`來指定預設佈局。第一種方法將從`grails-app/views/layouts/defaultLayout.gsp`載入佈局。.
至此,我將結束本期 Grails 1.3 功能的介紹。希望您能充分利用命名查詢!下次,我將介紹就地外掛。