Top Banner
GORM (Object Relational Mapping)
30

Gorm

Apr 13, 2017

Download

Technology

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Gorm

GORM(Object Relational Mapping)

Page 2: Gorm

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.

Page 3: Gorm

AgendaLet's Start

Domain Modelling in GORM

Persistence Basic

Querying with GORM

GORM and Constraints

Page 4: Gorm

Let's StartA 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 helloworldclass Person {

}

Page 5: Gorm

Basic Oprations Basic operations also know as CRUD:

1)Create2)Read3)Update4)Delete

Page 6: Gorm

CreatePerson p = new Person()p.name = “Vijay”p.age = 25p.lastVisit = new Date()p.save()

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

Page 7: Gorm

Read/Retrieveget(), 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.idNote*:- In case of get() and read() null is returned if the row with the specified id doesn't exist.

Page 8: Gorm

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.

Page 9: Gorm

UpdateTo update an instance, change some properties and then call save again:

def p = Person.get(1)p.name = "Bob"p.save()

Page 10: Gorm

DeleteTo delete an instance use the delete method:

def p = Person.get(1)p.delete()

Page 11: Gorm

Domain Modelling in Gorm1.Association in GORM

a.Many-To-One/One-To-Oneb.One-To-Manyc.Many-To-Many

2.Basic Collection Types3.Composition in GORM4.Inheritance in GORM5.Sets, List, Map

Page 12: Gorm

Many-To-One/One-To-OneUnidirectionalBidirectional

class Face { Nose nose}

class Nose {}

class Face { Nose nose}

class Nose { static belongsTo = [face:Face]}

Page 13: Gorm

One-To-manyA 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 { static hasMany = [books: Book] String name}

class Book { String title}

Page 14: Gorm

The default cascading behaviour is to cascade saves and updates, but not deletes unless a belongsTo is also specified:

class Author { static hasMany = [books: Book] String name}

class Book { static belongsTo = [author: Author] String title}

Page 15: Gorm

Many-to-manyGrails 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 { static belongsTo = Author static hasMany = [authors:Author] String title}

class Author { static hasMany = [books:Book] String name}

Page 16: Gorm

Composition in gormGrails 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 { Address homeAddress Address workAddress static embedded = ['homeAddress', 'workAddress']}

class Address { String number String code}

Page 17: Gorm

Inheritance in gormGORM supports inheritance both from abstract base classes and concrete persistent GORM entities.

class Content { String author}

class BlogEntry extends Content { URL url}

class Book extends Content { String ISBN}

def content = Content.list() // list all blog entries and bookscontent = Content.findAllByAuthor('Joe Bloggs') // find all by author

Page 18: Gorm

Persistence BasicSaving and UpdatingDeleting ObjectsCascading Updates and DeleteEager and Lazy FetchingPessimistic and Optimistic LockModification Checking

Page 19: Gorm

Persistence BasicsA 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.

Page 20: Gorm

Saving and Updatingdef 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)

Page 21: Gorm

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}

Page 22: Gorm

Eager and lazy fetchingclass Airport { String name static hasMany = [flights: Flight]}

class Flight { String number Location destination static belongsTo = [airport: Airport]}

class Location { String city String country}

def airport = Airport.findByName("Gatwick")for (flight in airport.flights) { println flight.destination.city}

GORM will execute a single SQL query to fetch the Airport instance, another to get its flights, and then 1 extra query 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).

Page 23: Gorm

Configuring eager fetchingclass Airport { String name static hasMany = [flights: Flight] static mapping = { flights lazy: false }}

Page 24: Gorm

Modification checkingisDirty:- 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 = paramsdef 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 }}

Page 25: Gorm

Querying with GORMDynamic FinderWhere QueriesCriteriaDetached CriteriaHQL

Page 26: Gorm

Advanced gorm featuresGORM 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 validatedafterInsert - Executed after an object is persisted to the databaseafterUpdate - Executed after an object has been updatedafterDelete - Executed after an object has been deletedonLoad - Executed when an object is loaded from the databaseTo add an event simply register the relevant method with your domain class.

Page 27: Gorm

Custom ORM mappingCustom 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}

Page 28: Gorm

Table and Columns nameclass 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 }}

Page 29: Gorm

GORM and Constraintshttps://grails.github.io/grails-doc/3.0.x/guide/GORM.html#basicCollectionTypes

Page 30: Gorm

Referencehttps://grails.github.io/grails-doc/3.0.x/guide/GORM.html