Grails 标准预测 - 获取行数
Posted
技术标签:
【中文标题】Grails 标准预测 - 获取行数【英文标题】:Grails criteria projections - get rows count 【发布时间】:2011-01-20 15:04:57 【问题描述】:我有酒店实体:
class Hotel
City city
现在,我需要指定城市的酒店数量。 可以这样实现:
def hotels = Hotel.findAllByCity(city)
def cnt = hotels.size()
但这是非常肮脏的方式。似乎有标准会更好,但我不知道如何实现它......
【问题讨论】:
【参考方案1】:Dave is right,您可以使用countBy* 方法进行简单计数。如果您需要两个以上的条件,则必须恢复为 criteria api、HQL 或 SQL。需要两个以上的标准是很常见的,尤其是对于一个活跃且不断发展的代码库。
这是一个示例,说明如何使用Criteria api 执行projections:
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 plugin)
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
【讨论】:
为简单起见,如何将标准放在一行中?我应该为每条语句添加分号 (;) 吗? 相信你可以做到:Hotel.createCriteria().count gt("stars", 2); eq("城市", 城市); eq("deleted", false) 但我还没试过。 如果我想知道哪些城市有不止一家酒店? 看起来 GORM 条件查询中不支持“have”子句,但在 HQL 中。【参考方案2】:在域对象上有动态计数器和查找器:
Hotel.countByCity(city)
更多详情当然在user guide 中
【讨论】:
以上是关于Grails 标准预测 - 获取行数的主要内容,如果未能解决你的问题,请参考以下文章