Если я правильно понимаю, мы можем получить желаемое количество конкретных результатов для разбивки на страницы, передав значения max и offset методу list
. Но во многих случаях мы также хотим показать общее количество результатов, возвращаемых SQL-запросом. По моему мнению, при смещении и максимальных значениях, переданных методу list
, SQL-запрос по-прежнему возвращает все результаты внутренне, но результаты обрезаются в соответствии с значениями max и offset. Есть ли способ получить общее количество результатов, полученных до обрезки?В Grails, как получить итоговый результат, когда мы передаем значения max и offset методу списка?
ответ
Если задан максимальный, метод список() возвращает PagedResultList, который имеет свойство TOTALCOUNT
def list = DomainClass.list(params) { }
log.debug "Total records: $list.totalCount"
render view:'list', model: [list:list, totalRecords:list.totalCount]
Вы не правильно понимаете :)
Было бы сумасшедшим, чтобы получить все записи сосчитать их и отфильтровывать те, которые не должны были быть возвращены клиенту. Это было бы не так уж плохо с несколькими строками, но учитывайте последствия такого подхода, как таблицы с миллионами или миллиардами строк.
Вместо этого вам необходимо выполнить два запроса. Один для извлечения строк, которые вы хотите, делая фильтрацию в базе данных, а другой с теми же ограничениями условий предложения, но без значений max и offset и с использованием select count ...
.
Как @sudhir указывает в своем ответе, Grails возвращает реализацию пользовательских List
(PagedResultList
), который включает в себя результаты для текущей страницы и имеет метод getTotalCount
для возврата результата из счета запроса.
Реализация метода list
является here, и вы можете увидеть в PagedResultList источника, счетчик запросов лениво запустить только тогда, когда вы звоните getTotalCount
.
Grails Критерии запроса и нумерацией страниц 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
Выход
{
"data": [
{
"id":1,
"firstName":name
},
{
"id":2,
"firstName":name
}
],
"totalRecord":5
}
Немного объяснения с вашим кодом или что вы изменили бы полезно. – Jhecht
Хороший пример, но параметры max и offset не используются. –