An Introduction to Groovy and Grails
by Harshad Oak
10/25/2006
Developing a Grails Application: Application Structure
For years I have been planning to develop an application that will help me manage my clothes—an application that will tell me where my favorite t-shirt is placed, if it is washed, if it is ironed, and so on. One day I intend to make millions selling this application, but for the time being I'll use it for my Grails example.
The first step is creating a Grails project directory structure. For that I will create a new directory at
C:\groovy\grailsapps and open a command prompt window at that level. Here, execute the command
grails create-app. You will be asked to enter an application name. Enter
ClothesMgt. Grails will display all the directories and files it has created for you. Figure 1 shows the resulting directory structure.
Figure 1: Grails project directory structure
The command will result in the creation of about 800 KB of files and directories. The idea here is that the framework is going with established Web application development conventions, so it creates files and directories that would be useful in a majority of Web applications. Although some may not like this idea of being forced into a certain structure, this auto-generation based on conventions is where the RAD features of Grails come from.
If you take a closer look at these directories, you will see that there are directories for things like controllers, views, tests, configuration files, and tag libraries. You will also find some basic JavaScript and CSS files in place. So the basic structure of you app is now in place. You just fill in the blanks and the application will be ready.
Note that the commands that autogenerate directories and files are optional. You can do all the file and directory creation manually. If you are familiar with Apache Ant, you can even open up the file
\src\grails\build.xml in the
GRAILS_HOME directory and look at exactly what each Grails command is trying to achieve.
Database
For this example I will use a MySQL database named
Clothes_Grails running on
localhost. An HSQL database comes built-in with Grails and can be useful for testing simple applications or just trying out Grails. If you use the HSQL DB, you will not have to execute the next few steps. I am using MySQL to demonstrate how easily you can use any database other than HSQL.
Download the MySQL driver from
http://www.mysql.com/products/connector/j/ and place the
mysql-connector-java-<version number>-stable-bin.jar file in the
ClothesMgt\lib directory. Next you need to edit the file
ClothesMgt\grails-app\conf\ApplicationDataSource.groovy.
The contents of the file will now be similar to the following:
class ApplicationDataSource {
boolean pooling = true
String dbCreate = "create-drop"
String url = "jdbc:mysql://localhost/Clothes_Grails"
String driverClassName = "com.mysql.jdbc.Driver"
String username = "grails"
String password = "groovy"
}
Now let's take a look at how you can make use of this database and object relational mapping.
Domain Classes
Grails' Object Relational Mapping (GORM) capability uses Hibernate 3 internally, but you do not need to be aware of, or change, any Hibernate settings. Grails has something called "domain classes," whose objects are mapped to the database. You can link domain classes using relationships, and they also provide very powerful dynamic methods for CRUD (Create/Read/Update/Delete) operations.
For this example let's create three domain classes named Shirt, Trouser, and Cabinet. To create a domain class, just run the command
grails create-domain-class. Remember to run this command within your project directory and not in the directory above it. This is a common mistake that, although I have cautioned you, you will commit at least once.
The only input you must provide to the
create-domain-class command is the class name. Run the command three times, giving Shirt, Trouser, and Cabinet as the names of the three domain classes. Grails will now create the domain classes in the directory
grails-app/domain/. These will have just two properties
id and
version. I will add properties to the classes to make them more representative of a shirt, trouser, and a cabinet.
Listing 1: Cabinet.groovy
class Cabinet {
Long id
Long version
String name
String location
def relatesToMany = [ shirts : Shirt, trousers : Trouser ]
Set shirts = new HashSet()
Set trousers = new HashSet()
String toString() { "${this.class.name} : $id" }
boolean equals(other) {
if(other?.is(this))return true
if(!(other instanceof Cabinet)) return false
if(!id || !other?.id || id!=other?.id) return false
return true
}
int hashCode() {
int hashCode = 0
hashCode = 29 * (hashCode + ( !id ? 0 : id ^ (id >>> 32)) )
}
}
Listing 2: Trouser.groovy
class Trouser {
Long id
Long version
String name
String color
Cabinet cabinet
def belongsTo = Cabinet
String toString() { "${this.class.name} : $id" }
boolean equals(other) {
if(other?.is(this))return true
if(!(other instanceof Trouser)) return false
if(!id || !other?.id || id!=other?.id) return false
return true
}
int hashCode() {
int hashCode = 0
hashCode = 29 * (hashCode + ( !id ? 0 : id ^ (id >>> 32) ) )
}
}
Listing 3: Shirt.groovy
class Shirt {
Long id
Long version
String name
String color
Cabinet cabinet
def belongsTo = Cabinet
String toString() { "${this.class.name} : $id" }
boolean equals(other) {
if(other?.is(this))return true
if(!(other instanceof Shirt)) return false
if(!id || !other?.id || id!=other?.id) return false
return true
}
int hashCode() {
int hashCode = 0
hashCode = 29 * (hashCode + ( !id ? 0 : id ^ (id >>> 32)))
}
}
The only lines I have added are the ones where I declare the field names and color and then when I declare the relationship between Cabinet and Shirt and Trouser. Every Shirt and Trouser belongs to the Cabinet, and the Cabinet has a set of shirts and trousers. The
belongsTo property is optional in this case, because in a one-many relationship, Grails always considers the one side as the owner. So you do not need to explicitly state so. Here I have done that just to make the relation obvious.
Next let's look at the controller and view part of a Grails application.