Reputation: 1750
If I understand correctly, we can retrieve the desired number of specific results for pagination by passing the max and offset values to the list
method. But, in many cases, we also want to show the total number of results returned by the SQL query. As per my understanding, with the offset and max values passed to the list
method, the SQL query still returns all the results internally but the results are trimmed according to the max and offset values. Is there any way to get the total number of results returned before trimming occurs?
Upvotes: 2
Views: 3103
Reputation: 11
Grails Criteria Query and pagination params
params.max = params?.max as Integer ?: 10
params.offset = params?.offset as Integer ?: 0
params.sort = params?.sort ?: "email"
params.order = params?.order ?: "asc"
params.filter = params?.filter ?: ""
params.packet = params?.packet ?: ""
def members = Member.createCriteria().list(params)
{
or
{
if(params.filter != ""){
ilike("firstName", "%" + params.filter + "%")
ilike("lastName", "%" + params.filter + "%")
ilike("email", "%" + params.filter + "%")
try {
params.filter as Long
eq("citizenId" , params.filter.toLong())
}catch (e) {
}
ilike("mobile", "%" + params.filter + "%")
}
}
}
def dataMembers = [:]
dataMembers.data = members
dataMembers.totalRecord = members.totalCount
render dataMembers as JSON
Output
{
"data": [
{
"id":1,
"firstName":name
},
{
"id":2,
"firstName":name
}
],
"totalRecord":5
}
Upvotes: 1
Reputation: 75671
You do not understand correctly :)
It would be crazy to retrieve all of the records to count them and filter out the ones that shouldn't have been returned at the client. It wouldn't be that bad with a few rows, but consider the performance implications of an approach like that with tables that have millions or billions of rows.
Instead, you have to execute two queries. One to retrieve the rows that you want, doing the filtering in the database, and another with the same where clause restrictions but without the max and offset values, and using select count ...
.
As @sudhir points out in his answer, Grails will return a custom List
implementation (PagedResultList
) which includes the results for the current page and has a getTotalCount
method to return the result from the count query.
The implementation of the list
method is here and you can see in the PagedResultList source that the count query is lazily run only when you call getTotalCount
.
Upvotes: 5
Reputation: 4096
When max is specified, list() method returns PagedResultList which has a totalCount property
def list = DomainClass.list(params) { }
log.debug "Total records: $list.totalCount"
render view:'list', model: [list:list, totalRecords:list.totalCount]
Upvotes: 4