Java Grails 标准预测 - 获取行数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2327743/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 06:12:08  来源:igfitidea点击:

Grails criteria projections - get rows count

javahibernategrails

提问by Oleksandr

I have Hotel entity:

我有酒店实体:

class Hotel {
City city
}

Now, i need count of hotels with given city. It could be done in this way:

现在,我需要给定城市的酒店数量。可以通过以下方式完成:

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

But it's very dirtyway. It seems that with criteria it would be better, but i have no idea how to implement it...

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

采纳答案by Dave Bower

There are dynamic counters as well as finders on domain objects:

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

Hotel.countByCity(city)

More details in the user guide, of course

当然,用户指南中有更多详细信息

回答by Colin Harrington

Dave is rightthat you can use the countBy*methods for simple counting. If you need more than two criteria you will have to revert to the criteria api, HQLor SQL. It is very common to need more than two criteria especially with an active and evolving codebase.

Dave 是对的,您可以使用countBy*方法进行简单计数。如果您需要两个以上的条件,则必须恢复到条件 apiHQL或 SQL。需要两个以上的标准是很常见的,尤其是在活跃和不断发展的代码库中。

Here is an example of how you would use the Criteria apito do projections:

以下是如何使用Criteria api进行投影的示例:

def c = Hotel.createCriteria()

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

}

Alternatively (more elegantly) you could even use Criteria#count like the following:

或者(更优雅),您甚至可以使用 Criteria#count 如下所示:

def c = Hotel.createCriteria()

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

}

Just for completeness sake:

只是为了完整起见:

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

class City {
    String name
}

An integration test (using the build-test-data plugin)

集成测试(使用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
    }
}