Критерии Grails - получить количество строк - PullRequest
17 голосов
/ 24 февраля 2010

У меня есть гостиничный объект:

class Hotel {
City city
}

Теперь мне нужно количество отелей с указанным городом. Это можно сделать следующим образом:

def hotels = Hotel.findAllByCity(city)
def cnt = hotels.size()

Но это очень грязный способ. Кажется, что с критериями было бы лучше, но я понятия не имею, как это реализовать ...

Ответы [ 2 ]

46 голосов
/ 25 февраля 2010

Дэйв прав , что вы можете использовать countBy * методы для простого подсчета. Если вам нужно более двух критериев, вам придется вернуться к критериям api , HQL или SQL. Очень часто требуется более двух критериев, особенно с активной и развивающейся кодовой базой.

Ниже приведен пример использования Criteria api для выполнения проекций :

def c = Hotel.createCriteria()

def hotelCount = c.get {
    projections {
        count('id')
    }
    gt("stars", 2)          
    eq("city", city)            
    eq("deleted", false)

}

В качестве альтернативы (более элегантно) вы могли бы даже использовать Criteria # count следующим образом:

def c = Hotel.createCriteria()

def hotelCount = c.count {
    gt("stars", 2)          
    eq("city", city)            
    eq("deleted", false)

}

Просто для полноты:

class Hotel {
    City city
    Boolean deleted = false
    Integer stars
}

class City {
    String name
}

Интеграционный тест (с использованием плагина build-test-data )

import grails.test.*

class HotelTests extends GrailsUnitTestCase {

    void testCriteria() {
        City city1 = City.build(name:'one')
        assertNotNull(city1)
        City city2 = City.build(name:'two')
        assertNotNull(city1)

        Hotel fiveStarHotel= Hotel.build(city:city1, deleted:false, stars:5)
        assertNotNull(fiveStarHotel)

        Hotel hotelInCity2 = Hotel.build(city:city2, deleted:false, stars:5)
        assertNotNull(hotelInCity2)

        Hotel deletedHotel = Hotel.build(city:city1, deleted:true, stars:5)
        assertNotNull(deletedHotel)

        Hotel threeStarHotel = Hotel.build(city:city1, deleted:false, stars:3)
        assertNotNull(threeStarHotel)

        Hotel oneStarHotel = Hotel.build(city:city1, deleted:false, stars:1)
        assertNotNull(oneStarHotel)

        def c = Hotel.createCriteria()

        def hotelCount = c.get {
            projections {
                count('id')
            }
            gt("stars", 2)          
            eq("city", city1)           
            eq("deleted", false)

        }
        assertEquals(2, hotelCount) //should only find the 5 and 3 star hotel

        def c2 = Hotel.createCriteria()
        hotelCount = c2.count {
            gt("stars", 2)          
            eq("city", city1)           
            eq("deleted", false)

        }
        assertEquals(2, hotelCount) //should only find the 5 and 3 star hotel
    }
}
23 голосов
/ 24 февраля 2010

Существуют динамические счетчики, а также средства поиска для объектов домена:

Hotel.countByCity(city)

Подробнее в руководстве пользователя , конечно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...