Sei sulla pagina 1di 30

GORM

(Object Relational Mapping)


Object Relational Mapping(GORM)

GORM is Grails' object relational mapping (ORM) implementation.

Under the hood it uses Hibernate 3 and less configuration involved


in creating Grails domain classes.
Agenda
Let's Start

Domain Modelling in GORM

Persistence Basic

Querying with GORM

GORM and Constraints


Let's Start
A domain class can be created with the create-domain-class command:

grails create-domain-class helloworld.Person

This will create a class at the location grails-app/domain/helloworld/Person.groovy such as the


one below:

package helloworld
class Person {

}
Basic Oprations
Basic operations also know as CRUD:

1)Create
2)Read
3)Update
4)Delete
Create
Person p = new Person()
p.name = Vijay
p.age = 25
p.lastVisit = new Date()
p.save()

Person p = new Person(name: "Fred", age: 40, lastVisit: new Date())


p.save()
Read/Retrieve
get(), read(), load()
get():- Retrieves an instance of the domain class for the specified id.
read():- Retrieves an instance of the domain class for the specified id in a read-only state.
load():- Returns a proxy instance of the domain class for the given identifier.
Ex:- def p = Person.get(1)
assert 1 = p.id
Note*:- In case of get() and read() null is returned if the row with the specified id doesn't exist.
get() vs read() vs load()
get() vs read()
The read method is similar to the get method except that automatic dirty detection(check all the
properties) is disabled.
The instance isn't truly read-only - you can modify it - but if it isn't explicitly saved but has been modified, it
won't be updated in the database during a flush.
get() vs load()
get() returns null if data is not found in session as well as database, but load() returns
ObjectNotFoundException().
get() always return completely initialized object while load() may be not.
Update
To update an instance, change some properties and then call save again:

def p = Person.get(1)
p.name = "Bob"
p.save()
Delete
To delete an instance use the delete method:

def p = Person.get(1)
p.delete()
Domain Modelling in Gorm
1.Association in GORM
a.Many-To-One/One-To-One
b.One-To-Many
c.Many-To-Many
2.Basic Collection Types
3.Composition in GORM
4.Inheritance in GORM
5.Sets, List, Map
Many-To-One/One-To-One
Unidirectional Bidirectional

class Face { class Face {


Nose nose Nose nose
} }

class Nose { class Nose {


} static belongsTo = [face:Face]
}
One-To-many
A one-to-many relationship is when one class, has many instances of another class. With
Grails you define such a relationship with the hasMany setting:

class Author { class Book {


static hasMany = [books: Book] String title
String name }
}
The default cascading behaviour is to cascade saves and updates, but not deletes unless a belongsTo is
also specified:

class Author { class Book {


static hasMany = [books: Book] static belongsTo = [author: Author]
String name String title
} }
Many-to-many
Grails supports many-to-many relationships by defining a hasMany on both sides of the relationship and
having a belongsTo on the owned side of the relationship:

class Book { class Author {


static belongsTo = Author static hasMany = [books:Book]
static hasMany = [authors:Author] String name
String title }
}
Composition in gorm
Grails supports the notion of composition. In this case instead of mapping classes onto separate tables a
class can be "embedded" within the current table.

class Person { class Address {


Address homeAddress String number
Address workAddress String code
static embedded = ['homeAddress', 'workAddress'] }
}
Inheritance in gorm
GORM supports inheritance both from abstract base classes and concrete persistent GORM entities.

class Content { class BlogEntry extends Content { class Book extends Content {
String author URL url String ISBN
} } }

def content = Content.list() // list all blog entries and books


content = Content.findAllByAuthor('Joe Bloggs') // find all by author
Persistence Basic
Saving and Updating
Deleting Objects
Cascading Updates and Delete
Eager and Lazy Fetching
Pessimistic and Optimistic Lock
Modification Checking
Persistence Basics
A key thing to remember about Grails is that under the surface Grails is using
Hibernate for persistence.

Grails automatically binds a Hibernate session to the currently executing request.


This lets you use the save and delete methods as well as other GORM methods
transparently.
Saving and Updating
def p = Person.get(1)
p.save()

This save will be not be pushed to the database immediately - it will be pushed when the
next flush occurs.
But there are occasions when you want to control when those statements are executed or, in
Hibernate terminology, when the session is "flushed". To do so you can use the flush
argument to the save method:

def p = Person.get(1)
p.save(flush: true)
Another thing to bear in mind is that Grails validates a domain instance every time
you save it. If that validation fails the domain instance will not be persisted to the
database. By default, save() will simply return null in this case, but if you would
prefer it to throw an exception you can use the failOnError argument:

def p = Person.get(1)
try {
p.save(failOnError: true)
}
catch (ValidationException e) {
// deal with exception
}
Eager and lazy fetching
class Airport {
String name def airport = Airport.findByName("Gatwick")
for (flight in airport.flights) {
static hasMany = [flights: Flight] println flight.destination.city
} }

class Flight { GORM will execute a single SQL query to fetch the Airport
String number
instance, another to get its flights, and then 1 extra query
Location destination
static belongsTo = [airport: Airport] for each iteration over the flights association to get the
} current flight's destination. In other words you get N+1
queries (if you exclude the original one to get the airport).
class Location {
String city
String country
}
Configuring eager fetching
class Airport {
String name
static hasMany = [flights: Flight]
static mapping = {
flights lazy: false
}
}
Modification checking
isDirty:- You can use the isDirty method to check if any field has been modified:
getDirtyPropertyNames:- You can use the getDirtyPropertyNames method to retrieve the names of
modified fields; this may be empty but will not be null.
getPersistentValue:- You can use the getPersistentValue method to retrieve the value of a modified field

def airport = Airport.get(10)


assert !airport.isDirty()
airport.properties = params
def modifiedFieldNames = airport.getDirtyPropertyNames()
for (fieldName in modifiedFieldNames) {
def currentValue = airport."$fieldName"
def originalValue = airport.getPersistentValue(fieldName)
if (currentValue != originalValue) {
// do something based on changed value
}
}
Querying with GORM
Dynamic Finder
Where Queries
Criteria
Detached Criteria
HQL
Advanced gorm features
GORM supports the registration of events as methods that get fired when certain events occurs
such as deletes, inserts and updates. The following is a list of supported events:
beforeInsert - Executed before an object is initially persisted to the database. If you return false,
the insert will be cancelled.
beforeUpdate - Executed before an object is updated. If you return false, the update will be
cancelled.
beforeDelete - Executed before an object is deleted. If you return false, the delete will be
cancelled.
beforeValidate - Executed before an object is validated
afterInsert - Executed after an object is persisted to the database
afterUpdate - Executed after an object has been updated
afterDelete - Executed after an object has been deleted
onLoad - Executed when an object is loaded from the database
To add an event simply register the relevant method with your domain class.
Custom ORM mapping
Custom mappings are defined using a static mapping block defined within your domain class:
class Person {

static mapping = {
version false
autoTimestamp false
}
}
You can also configure global mappings in application.groovy (or an external config file) using this setting:
grails.gorm.default.mapping = {
version false
autoTimestamp false
}
Table and Columns name
class Person {

static mapping = {
table 'people'
}
}
class Person {
String firstName
static mapping = {
table 'people'
firstName column: 'First_Name'
}
}
class Address {
String number
String postCode
static mapping = {
postCode type: PostCodeType
}
}
GORM and Constraints
https://grails.github.io/grails-doc/3.0.x/guide/GORM.html#basicCollectionTypes
Reference
https://grails.github.io/grails-doc/3.0.x/guide/GORM.html

Potrebbero piacerti anche