Grails标准投影 – 获取行数

我有酒店实体:

class Hotel { City city } 

现在,我需要一定数量的酒店与给定的城市。 它可以这样做:

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

但这是非常肮脏的方式。 似乎有了标准会更好,但我不知道如何实现它……

域对象上有动态计数器和查找程序:

 Hotel.countByCity(city) 

当然, 用户指南中有更多细节

Dave是对的 ,您可以使用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#计数:

 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 } }