1. Overview

This is a quick intro to Grails 3 and GORM.

We’re going to of course use Groovy and – implicitly – the framework also makes use of Hibernate for ORM, the Spring Framework for Dependency Injection, SiteMash for layout and themes, etc.

2. DataSource Configuration

We can start without having to specify any explicit data source configuration – by default Grails uses the HSQLDB database for the development and testing environments.

But if you want to change these defaults, you can define your selected data-source in the application.yml:

environments:
    development:
        dataSource:
             driverClassName : "com.mysql.jdbc.Driver"           
             url : "jdbc:mysql://localhost:8080/test"
             dialect : org.hibernate.dialect.MySQL5InnoDBDialect

Similarly we can create multiple environments here, next to development if we need to.

3. Domain

Grails is capable of creating the database structure for our domain classes, based on the dbCreate property in the database configuration.

Let’s define one of these domain classes here:

Class User {
    String userName
    String password
    String email
    String age
    static constraints = {
        userName blank: false, unique: true
        password size: 5..10, blank: false
        email email: true, blank: true
    }
}

Note how we’re specifying our validation constraints right in the model, which keeps things nice and clean, and annotation-free.

These constraints will be checked by Grails automatically when the entity is being persisted and the framework will throw appropriate validation exceptions if any of these constraints are broken.

We can also specify GORM mappings in mapping property of the model:

static mapping = { sort "userName" }

Now if we call User.list() – we’ll get back results sorted by username.

We could of course achieve the same result by passing in the sort to the list API:

User.list(sort: "userName")

4. CRUD Operations

When we look at API operations, scaffolding plays a very interesting role in the beginning; it lets you generate basic a CRUD API for a domain class, including:

  • The necessary views
  • Controller actions for the standard CRUD operations
  • Two types: Dynamic and Static

Here’s how that works with dynamic scaffolding:

class UserController {
    static scaffold = true
}

By just writing this single line, the framework will generate 7 methods at runtime: show, edit, delete, create, save and update. These will be published as the API for that particular domain entity.

Example of Static scaffolding:

  • To create a view with scaffolding use: “grails generate-views User
  • To create the controller and view with scaffolding use: “grails generate-controller User
  • To create everything in single command, use: “grails generate-all User

These commands will auto-generate the necessary plumbing for that particular domain object.

Let’s now have a very quick look at using these operations – for example, for our User domain object.

To create new “user” record:

def user = new User(username: "test", password: "test123", email: "[email protected]", age: 14)
user.save()

To fetch a single record:

def user = User.get(1)

This get API will retrieve the domain object in an editable mode. For a read-only mode, we can use the read API:

def user = User.read(1)

To update existing record:

def user = User.get(1)
user.userName = "testUpdate"
user.age = 20
user.save()

And a simple delete operation for an existing record:

def user = User.get(1)
user.delete()

5. GORM Queries

5.1. find

Let’s start with the find API:

def user = User.find("from User as u where u.username = 'test' ")

We can also use a different syntax to pass in the parameter:

def user = User.find("from User as u where u.username?", ['test'])

We can also use a named parameter:

def user = User.find("from User as u where u.username=?", [username: 'test'])

5.2. findBy

Grails provides a dynamic finder facility which uses domain properties to execute a query at runtime and return the first matching record:

def user = User.findByUsername("test")
user = User.findByUsernameAndAge("test", 20)
user = User.findByUsernameLike("tes")
user = User.findByUsernameAndAgeNotEquals("test", "100")

You can find more expressions here.

5.3. Criteria

We can also retrieve data using some flexible criteria:

def user = User.find { username == "test"}
def user = User.createCriteria()
def results = user.list {
    like ("userName", "te%")
    and 
    {
        between("age", 10, 20)
    }
    order("userName", "desc")
}

A quick note here – when using a criteria query, use “{ }” instead of “( )”.

5.4. Execute Query/Update

GORM also support the HQL query syntax – for read operations:

def user = User.executeQuery(
  "select u.userName from User u where u.userName = ?", ['test'])

As well as write operations:

def user = User.executeUpdate("delete User u where u.username =?", ['test'])

6. Conclusion

This has been a very quick intro to Grails and GORM – to be used as a guide to getting started with the framework.