Groovy for Domain-specific Languages - Second Edition

(nextflipdebug2) #1

Existing Groovy DSLs


[ 240 ]

Dynamic finders

GORM supports a unique and powerful query function through the use of dynamic
finders. A dynamic finder is a pretended method applied to a domain class, which
can return one or many queried objects. Finders work by allowing us to invent
method names, where the syntax of the query is bound into the method name.
All finders are prefixed by findBy or findAllBy:


// Find the first customer called Fred
def fred = Customer.findByFirstName("Fred")
// Find all Flintstones
def flintstones = Customer.findAllByLastName("Flintstone")
// Find Fred Flintstone
def fred_flintstoner = Customer.findByFirstNameAndLastName("Fred",
"Flintstone")

Finder names can also include comparators, such as Like, LessThan, and IsNotNull:


// Find all customers with names beginning with Flint
def flints = Customer.findAllByLastNameLike("Flint%")

We can include associations in queries. Here, we can find all invoices for Fred:


def fred = Customer.findByFirstNameAndLastName("Fred",
"Flintstone")
def invoices = Invoice.findAllByCustomer(fred)

Dynamic finders open up a huge range of possible finder methods that can be
used with a class. The more fields there are, the more possible finder methods
there are to match. Rather than trying to second-guess what all of the possible
combinations might be and adding them to the metaclass, GORM takes a
slightly different approach.


From Groovy 1.0, we can add a method called methodMissing to the MetaClass
object. This differs slightly from the invokeMethod call that we provided in previous
chapters because methodMissing is called as the last chance saloon before Groovy
throws a MethodMissingException, whereas invokeMethod will be called for every
method invocation.


In earlier version of Grails, it would add its own methodMissing implementation,
which catches all of the missing method invocations with the prefixes find
and findAll the first time that they occur. At this point, the actual method
implementations were registered in the metaClass, so subsequent calls to that finder
will not suffer the overhead. The later versions of Grails transform finders as they
are encountered in the code and turned them into individual Hibernate criteria
style queries.


http://www.ebook3000.com
Free download pdf