GORM Query HQL
HQL es la manera más descriptiva de hacer queries, el ide intellij permite autocompletado en este tipo de queries, por lo tanto pensamos que es la mejor opción para unificar los queries de un proyecto Grails. Si el query es sencillo se puede utilizar dynamic finders pero para queries complejos o descriptivos (deseamos el control total de lo que sucede) se debe utilizar hql.
En grails, una ventaja de hql con respecto a criteria es que hql no es dinámico, es decir no es necesario utilizar @GrailsCompileStatic(TypeCheckingMode.SKIP)
para que compile.
Criteria debe ser utilizado para armar queries donde se introduzca o quite ciertas partes del query en base a criterios, hacer esto con hql es tedioso porque se tiene que hacer directamente con el String del query mientras que con criteria se van agregando ifs y restricciones al criteria.
HQL sirve para hacer los queries orientados a objetos más potentes y descriptivos. La desventaja de este tipo de queries es que no son fuertemente tipados.
GORM tiene dos maneras de utilizar HQL. La primera es utilizando find()
o findAll()
del domain class. En esta manera, con DomainClass.find()
se regresa un objeto del domain class y DomainClass.findAll()
regresa una lista de objetos del domain class.
Si utilizas esta forma, estás limitado a solo especificar la cláusula where:
Transaction.findAll('from Transaction as t where t.product.manufacturer.id = 1')
find()
: Obtiene un único resultado, no es necesario poner el select al query
findAll()
: Obtiene una lista, no es necesario poner el select al query
Transaction.findAll('from Transaction as t where t.product.manufacturer.id = :companyId', [companyId: 1])
Se utiliza para hacer queries en donde el resultado NO es un objeto de cierto tipo (por ejemplo un count
o joins
) .Estos queries requieren la cláusula select
y retornan una lista de Arrays, cada elemento de la lista representa una fila y cada valor del array representa una columna:
String query = $/
select
s.name,
m.name,
p.name
from Transaction as t
inner join t.product as p
inner join t.store as s
inner join p.manufacturer as m
where t.product.manufacturer.id = :companyId
and t.salesDate between :startDate and :endDate
/$
List queryResults = Transaction.executeQuery(query,
[companyId: ACME.id, startDate: new Date('1/1/2014'), endDate: new Date('1/31/2014')]
)
def row = Notify.executeQuery(
"select count(*) from Notify where hotel.id=1 and leida=false")
return row.get(0)
join
abrevia inner join
left join
abrevia left outer join
right join
abrevia right outer join
Un fetch
join permite inicializar entidades o colecciones junto con sus objetos padre utilizando un solo select tal como sucede con lazy:false
. Los objetos asociados no son retornados directamente en el resultado del query, en vez de eso ellos pueden ser accedidos a través de su objeto padre.
Este parámetro sobreescribe la forma de traer el objeto/colección definida en la clase.