2010-02-24 9 views
15

मैं होटल इकाई है:Grails मापदंड अनुमानों - पंक्तियों गिनती हो

class Hotel { 
City city 
} 

अब, मैं दिया शहर के साथ होटल की गिनती की जरूरत है। यह इस तरीके से किया जा सकता है:

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

लेकिन यह बहुत गंदा तरीका है। ऐसा लगता है कि मापदंड के साथ यह बेहतर होगा, लेकिन मैं पता नहीं कैसे इसे लागू करने के ... है

उत्तर

23

वहाँ गतिशील काउंटरों के साथ ही डोमेन वस्तुओं पर ढूँढ़ने वाले हैं: user guide में

Hotel.countByCity(city) 

अधिक जानकारी , निश्चित रूप से

44

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) 

} 

वैकल्पिक रूप से (अधिक सुंदर ढंग से) मानदंड तुम भी इस्तेमाल कर सकते हैं # निम्नलिखित की तरह गिनती:

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

बस सादगी के लिए, मैं मानदंड को एक पंक्ति में कैसे रख सकता हूं? क्या मुझे प्रत्येक कथन के लिए अर्धविराम (;) जोड़ना चाहिए? –

+0

मेरा मानना ​​है कि आप कर सकते हैं: Hotel.createCriteria()। गिनती {gt ("stars", 2); ईक ("शहर", शहर); eq ("हटाया गया", झूठा)} लेकिन मैंने अभी तक यह कोशिश नहीं की है। –

+0

कोशिश की और परीक्षण किया ... यह काम कर रहा है! धन्यवाद! –

संबंधित मुद्दे