3. Definición y características
class Student {
String name
String lastname
String mail
static belongsTo = [university :
University]
static constraints = {
name blank: false
lastname blank:false
mail unique: true, email: true
}
}
• Métodos públicos por defecto
• Atributos privados por defecto
• Getters y Setters invocados sin estar
explicitos
• Mapeos contra la base de datos
• Relaciones con otras clases de dominio
• Constraints sobre atributos
• Constructor por defecto con parámetro
Map
• Métodos dinámicos para búsquedas
4. Constraints
Son configuraciones escritas en un DSL para Grails que permiten realizar
validaciones sobre las clases de dominio
Algunas de las más utilizadas:
• blank
• email
• inList
• max/min
• size/maxSize/minSize
• range
• unique
5. Mapeo entre clases de Dominio
• Permiten establecer relaciones bidireccionales
• Especifican el comportamiento del ORM al guardar o borrar instancias de
clases de dominio
• Permite a Grails generar las tablas intermedias para las relaciones
• Las instancias que son referenciadas en el hasMany se almacenan por default
en la clase Set de Java.
6. Relaciones one-to-one
class Face {
Nose nose
}
class Nose {
static belongsTo = [face : Face]
}
--------------------------------------------------
//Las llamdas a save o delete en Face van a aplicarse en cascada sobre Nose
new Face(nose:new Nose()).save()
7. Relaciones one-to-many
class Author {
static hasMany = [books: Book]
String name
}
class Book {
//static belongsTo = [author: Author]
String title
}
-----------------------------------------------------
//En este ejemplo Grails genera una tabla intermedia. El comportamiento defecto es
ejecutar en cascada saves y updates, pero los delete sobre autores. Para ello se debe
descomentar la línea belongsTo en book.
8. Relaciones many-to-many
En las relaciones many-to-
many se debe especificar
siempre el dueño de la
relación con belongsTo.
La clase owner será quien
difunda en cascada los
cambios
Sólo uno de los lados puede
ser dueño de la relación
class Book {
static belongsTo = Author
static hasMany = [authors:Author]
String title
}
class Author {
static hasMany = [books:Book]
String name
}
-------------------------------------
new Author(name:"Stephen King")
.addToBooks(new Book(title:"The Stand"))
.addToBooks(new Book(title:"The Shining"))
.save()
9. Relaciones embeded
Permiten utilizar la noción de
composición en Grails.
Sirve para agrupar campos que van
a ser utilizados por muchas clases
de dominio en una sola clase.
Los atributos de la clase embebida
se guardan en columnas de la tabla
de la clase contenedora
class Person {
Address homeAddress
Address workAddress
static embedded = ['homeAddress',
'workAddress']
}
class Address {
String number
String code
}
10. Acceso y búsqueda de instancias
Existen varios métodos para obtener las clases de dominio a través de GORM:
Listando las instancias
Obteniéndolas por id
Dynamic Finders
Where Queries
Criteria Queries
Hibernate Query Language (HQL)
11. Acceso y búsqueda de instancias
Listando las instancias
def books = Book.list()
//Permite paginación
def books = Book.list(offset:10, max:20)
//Permite búsquedas ordenadas por
//atributos
def books = Book.list(sort:"title",
order:"asc")
Obteniéndolas por id
def book = Book.get(23)
def books = Book.getAll(23, 93, 81)
12. Dynamic Finders
class Book {
String title
Date releaseDate
Author author
}
class Author {
String name
}
----------------------------------------------------
def book = Book.findByTitle("The Stand")
book = Book.findByTitleLike("Harry Pot%")
book = Book.findByReleaseDateBetween(firstDate, secondDate)
book = Book.findByReleaseDateGreaterThan(someDate)
book = Book.findByTitleLikeOrReleaseDateLessThan("%Something%",
someDate)
13. Criteria query
def c = Account.createCriteria()
def results = c {
between("balance", 500, 1000)
eq("branch", "London")
or {
like("holderFirstName", "Fred%")
like("holderFirstName", "Barney%")
}
maxResults(10)
order("holderLastName", "desc")
}
14. Atributos transient
class Author {
String name
String getUpperCaseName() {
name.toUpperCase()
}
static transients = ['upperCaseName']
}
---------------------------------------------------------
//Se utilizan para campos readonly que no se van a guardar en
//la base
16. Características y definición
Son las clases responsables de
manejar las llamadas Web
Cumplen el rol de controlador en el
modelo MVC
Por convención sus nombres
terminan siempre con el sufijo
controller
Por convención los nombres de los
métodos mapean a una URL de
alguna vista.
class ProjectController {
static allowedMethods = [save: "POST", update:
"POST", delete: "POST"]
def index() {
redirect(action: "list", params: params)
}
def list(Integer max) {
params.max = Math.min(max ?: 10, 100)
[projectInstanceList: Project.list(params),
projectInstanceTotal: Project.count()]
}
def create() {
[projectInstance: new Project(params)]
}
}