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