1、Criteria(條件查詢)
Criteria可以通過createCriteria 或者 withCriteria 方法來使用
1 def user = User.findByUserId(params.user) 2 def entries = Post.createCriteria().list { 3 and { 4 eq('user', user) 5 between('created', new Date()-1, new Date()) 6 tags { 7 eq('name', 'Grails') 8 } 9 } 10 maxResults(10) 11 order("created", "desc") 12 }
and:裏面所有查詢條件都是“與”關係(全部爲真)
tags:Tag對象
maxResults:記錄數
order:排序
1 def entries = Post.withCriteria { 2 and { 3 eq('user', user) 4 between('created', new Date()-1, new Date()) 5 } 6 }
在系統中增加一個高級查詢功能,用多條件組合查詢Profile
新建一個閉包com.grailsinaction.UserController/advResults
1 def advSearch = { 2 } 3 4 def advResults = { 5 def profileProps = Profile.metaClass.properties*.name 6 def profiles = Profile.withCriteria { 7 "${params.queryType}" { 8 params.each { field, value -> 9 if (profileProps.grep(field) && value) { 10 ilike(field, value) 11 } 12 } 13 } 14 } 15 [ profiles : profiles ] 16 }
新建一個查詢頁面views/user/advSearch.gsp
1 <html> 2 <head> 3 <title>Advanced Search</title> 4 <meta name="layout" content="main"/> 5 </head> 6 7 <body> 8 <formset> 9 <legend>Advanced Search for Friends</legend> 10 <table> 11 <g:form action="advResults"> 12 <tr> 13 <td>Name</td> 14 <td><g:textField name="fullName" /></td> 15 </tr> 16 <tr> 17 <td>Email</td> 18 <td><g:textField name="email" /></td> 19 </tr> 20 <tr> 21 <td>Homepage</td> 22 <td><g:textField name="homepage" /></td> 23 </tr> 24 <tr> 25 <td>Query Type:</td> 26 <td> 27 <g:radioGroup name="queryType" labels="['And','Or','Not']" values="['and','or','not']" value="and" >${it.radio} ${it.label}</g:radioGroup> 28 </td> 29 </tr> 30 <tr> 31 <td/> 32 <td><g:submitButton name="search" value="Search"/></td> 33 </tr> 34 </g:form> 35 </table> 36 </formset> 37 </body> 38 </html>
新建一個查詢結果返回頁面views/user/advResults
1 <html> 2 <head> 3 <title>Advanced Search Results</title> 4 <meta name="layout" content="main"/> 5 </head> 6 7 <body> 8 <h1>Advanced Results</h1> 9 <p>Searched for items matching <em>${term}</em>. Found <strong>${profiles.size()}</strong> hits. 10 </p> 11 <ul> 12 <g:each var="profile" in="${profiles}"> 13 <li>${profile.fullName}</li> 14 </g:each> 15 </ul> 16 <g:link action='advSearch'>Search Again</g:link> 17 </body> 18 </html>
2、Projections(投影)
投影被用於定製查詢結果。要使用投影你需要在criteria builder樹裏定義一個"projections"節點
1 def tagList = Post.withCriteria { 2 createAlias("user", "u") 3 createAlias("tags", "t") 4 eq("u.userId", "glen") 5 projections { 6 groupProperty("t.name") 7 count("t.id") 8 } 9 }
3、HQL
硬編碼
def results = Book.findAll("from Book as b where b.title like 'Lord of the%'")
位置參數
def results = Book.findAll("from Book as b where b.title like ?", ["The Shi%"])
命名參數
def results = Book.findAll("from Book as b where b.title like :search or b.author like :search", [search:"The Shi%"])
多行
1 def results = Book.findAll("""\\ 2 from Book as b, \\ 3 Author as a \\ 4 where b.author = a and a.surname = ?""", ['Smith'])
分頁排序
def results = Book.findAll("from Book as b where b.title like 'Lord of the%'", [max:10, offset:20, sort:"asc", order:"title"])
4、總結和最佳實踐
- Use scaffolds for instant gratification and to stay motivated:使用動態腳手架能給開發者帶來驚喜,如果願意就儘量使用吧
- Understand your customization options:可以使用調整css的方法調整界面,也可以修改腳手架模板代碼改善腳手架生成的外觀,只要願意
- Dynamic finders are fantastic for two-field queries:動態查詢器比較適合兩個參數的查詢
- Use the Grails console:善用console可以幫助我們調試程序
- Harness the power of criteria queries:提高使用criteria queries的能力,因爲那很重要
- Always use named params for HQL:慎用HQL,除非其他方法不能解決,如果一定要用,要使用命名參數,防止SQL注入攻擊
- Use bootstraps conditionally:使用bootstrap加入原始數據時,帶入環境條件,避免測試數據在生產環境出現
5、代碼清單
domain
package:com.grailsinaction
Post
Profile
User
Tag
controllers
package:com.grailsinactin
PostController
ProfileController
UserController
TagController
views
layout
main.gsp
user
advResults.gsp
advSearch.gsp
results.gsp
search.gst
error.gsp
test/integration
package:com.grailsinaction
PostIntegrationTests
UserIntegrationTests
QueryIntegrationTests
web-app
css
hubbub.css
images
backgroud.png
headerlogo.png
6、代碼打包下載