У меня есть объект Отеля:
class Hotel {
City city
}
Теперь, мне нужно количество отелей с данным городом. Это могло быть сделано таким образом:
def hotels = Hotel.findAllByCity(city)
def cnt = hotels.size()
Но это - очень грязный путь. Кажется, что с критериями это было бы лучше, но я понятия не имею, как реализовать его...
Есть динамические счетчики, а также средства поиска по объектам домена:
Hotel.countByCity(city)
Более подробная информация в руководстве пользователя , конечно же
Дэйв прав в том, что вы можете использовать методы 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
}
}