class Customer {
static transients = [“networth”]
static mapping = {
id column: ‘customer_id’
table ‘crc_customer’
columns {
name column: ‘customer_name’
}
}
well. Several features of the Groovy language make it easy
to write DSLs, including closures, literal lists and maps,
and a flexible syntax that does not, for example, require
parentheses around method arguments. They enable a
developer to write highly readable and concise DSLs without having to go outside of the language and use mechanisms such as XML.
def getNetworth() {
def networth = 0
accounts.each {networth + it.balance}
networth
}
…
}
MANIPULATING PERSISTENT OBJECTS
Applications need to save, load, and delete persistent
objects. A traditional ORM framework provides an API
object that has methods for manipulating persistent
data. GORM, however, takes a very different and simpler
approach that leverages Groovy’s ability to define new
methods at runtime.
In this example, the transients property, which is a list
of property names, specifies that the networth property,
which calculates the total balance of the customer’s
accounts and is defined by the getNetworth() method,
is not persistent. The mapping property maps the Cus-
tomer class to the crc_customer table; the id property to
the customer_id column; and the name property to the
customer_name property.
The value of the mapping property is a Groovy closure
object, which is a kind of anonymous method. Although
it might not be immediately apparent, the body of
the mapping closure is a
sequence of method calls.
For example, “id column:
‘customer_id’” is a call to
an id method with a map
parameter containing a
single entry that has column:
as the key and ‘customer_id’
as the value.
The mapping closure
is an example of a DSL
(domain-specific language), 11
which is a mini-language for
representing information
about a domain. DSLs are
used by Grails for a variety of configuration tasks.
Groovy applications often
define one or more DSLs as
THE TRADITIONAL WAY
When using a traditional ORM framework, the application manipulates persistent data by invoking methods on
an API object. For example, a Hibernate application uses
a Session object, which represents a connection to the
database to save, load, and delete persistent objects. Note
that usually an application needs only to save newly created objects. Most ORM frameworks, including Hibernate,
track changes to persistent objects and automatically
update the database.
Figure 3A shows a code snippet that illustrates how
an application can load an account with the specified
primary key. This code snippet obtains the current Session
and calls get() to load the specified account.
An application’s business logic could use the Session
L ongpk=…
S ession session = sessionFactory.getCurrentSession()
Account account = (Account) session.get( Account.class, pk)
A
i nterface AccountDao {
Account get(long accountId);
…
B
FIG 3
class AccountDaoImpl implements AccountDao {
public Account get(long accountId) {
Session session = sessionFactory.getCurrentSession()
return (Account) session.get( Account.class, pk)
}
}