Hibernate.orgCommunity Documentation
O Hibernate vem com uma poderosa linguagem de consulta (HQL) que é muito parecida com o SQL. No entanto, comparado com o SQL o HQL é totalmente orientado à objetos, e compreende noções de herança, polimorfismo e associações.
As Consultas não diferenciam maiúscula de minúscula, exceto pelo nomes das classes e propriedades Java. Portanto, SeLeCT
é o mesmo que sELEct
que é o mesmo que SELECT
, mas org.hibernate.eg.FOO
não é org.hibernate.eg.Foo
e foo.barSet
não é foo.BARSET
.
Esse manual usa as palavras chave HQL em letras minúsculas. Alguns usuários acreditam que com letras maiúsculas as consultas ficam mais legíveis, mas nós acreditamos que este formato não é apropriado para o código Java.
A consulta mais simples possível do Hibernate é a seguinte:
from eg.Cat
Isto simplesmente retornará todas as instâncias da classe eg.Cat
. Geralmente não precisamos qualificar o nome da classe, uma vez que o auto-import
é o padrão. Por exemplo:
from Cat
Com o objetivo de referir-se ao Cat
em outras partes da consulta, você precisará determinar um alias. Por exemplo:
from Cat as cat
Essa consulta atribui um alias a cat
para as instâncias de Cat
, portanto poderemos usar esse alias mais tarde na consulta. A palavra chave as
é opcional. Você também pode escrever assim:
from Cat cat
Classes múltiplas podem ser envolvidas, resultando em um produto cartesiano ou união "cruzada".
from Formula, Parameter
from Formula as form, Parameter as param
É considerada uma boa prática nomear alias de consulta, utilizando uma letra minúscula inicial, consistente com os padrões de nomeação Java para variáveis locais (ex.: domesticCat
).
Podemos também atribuir aliases em uma entidade associada, ou mesmo em elementos de uma coleção de valores, usando uma join
. Por exemplo:
from Cat as cat inner join cat.mate as mate left outer join cat.kittens as kitten
from Cat as cat left join cat.mate.kittens as kittens
from Formula form full join form.parameter param
Os tipos de uniões suportados foram inspirados no ANSI SQL:
inner join
left outer join
right outer join
união completa
(geralmente não é útil)
As construções inteiro
, união esquerda externa
e união direita externa
podem ser abreviadas.
from Cat as cat join cat.mate as mate left join cat.kittens as kitten
Você pode fornecer condições extras de união usando a palavra chave do HQL with
.
from Cat as cat left join cat.kittens as kitten with kitten.bodyWeight > 10.0
A "fetch" join allows associations or collections of values to be initialized along with their parent objects using a single select. This is particularly useful in the case of a collection. It effectively overrides the outer join and lazy declarations of the mapping file for associations and collections. See Seção 20.1, “Estratégias de Busca ” for more information.
from Cat as cat inner join fetch cat.mate left join fetch cat.kittens
Geralmente, uma união de busca não precisa atribuir um alias, pois o objeto associado não deve ser usado na cláusula where
(ou em qualquer outra cláusula). Também, os objetos associados não são retornados diretamente nos resultados da consulta. Ao invés disso, eles devem ser acessados usando o objeto pai. A única razão pela qual precisariamos de um alias é quando fazemos uma união de busca recursivamente em uma coleção adicional:
from Cat as cat inner join fetch cat.mate left join fetch cat.kittens child left join fetch child.kittens
Observe que a construção busca
não deve ser usada em consultas invocadas usando iterate()
(embora possa ser usado com scroll()
). O Fetch
também não deve ser usado junto com o setMaxResults()
ou setFirstResult()
pois essas operações são baseadas nas linhas retornadas, que normalmente contém duplicidade devido à busca das coleções, então o número de linhas pode não ser o que você espera. A Fetch
não deve ser usada junto com uma condição with
. É possível que seja criado um produto cartesiano pela busca de união em mais do que uma coleção em uma consulta, então tome cuidado nesses casos. Uma busca de união em várias coleções pode trazer resultados inesperados para mapeamentos do tipo bag, tome cuidado na hora de formular consultas como essas. Finalmente, observe o seguinte, a busca de união completa
e busca de união direita
não são importantes.
Se estiver usando o nível de propriedade busca lazy (com instrumentação de bytecode), é possível forçar o Hibernate a buscar as propriedades lazy imediatamente na primeira consulta, usando buscar todas as propriedades
.
from Document fetch all properties order by name
from Document doc fetch all properties where lower(doc.name) like '%cats%'
O HQL suporta duas formas de associação para união: implícita
e explícita
.
As consultas apresentadas na seção anterior usam a forma explícita
, onde a palavra chave união é explicitamente usada na cláusula from. Essa é a forma recomendada.
A forma implícita
não usa a palavra chave "união". Entretanto, as associações são "diferenciadas" usando pontuação ("." - dot-notation). Uniõesimplícitas
podem aparecer em qualquer uma das cláusulas HQL. A união implícita
resulta em declarações SQL que contém uniões inteiras.
from Cat as cat where cat.mate.name like '%s%'
Geralmente, existem duas formas para se referir à propriedade do indentificador de uma entidade:
A propriedade especial (em letra minúscula) id
pode ser usada para se referir à propriedade do identificador de uma entidade considerando que a entidade não define uma propriedade não identificadora chamada id.
Se a entidade definir a propriedade do identificador nomeada, você poderá usar este nome de propriedade.
As referências à composição das propriedades do identificador seguem as mesmas regras de nomeação. Se a entidade tiver uma propriedade de não identificador chamada id, a composição da propriedade do identificador pode somente ser referenciada pelo seu nome definido. Do contrário, uma propriedade especial id
poderá ser usada para referenciar a propriedade do identificador.
Observe: esta ação mudou completamente na versão 3.2.2. Nas versões anteriores o id
sempre referia-se à propriedade do identificador não importando seu nome atual. Uma ramificação desta decisão era que as propriedades do não identificador de chamadas id
nunca poderiam ser referenciadas nas consultas do Hibernate.
A cláusula select
seleciona quais objetos e propriedades retornam no resultado da consulta. Considere:
select mate from Cat as cat inner join cat.mate as mate
A consulta selecionará mate
s (parceiros), de outros Cat
s. Atualmente, podemos expressar a consulta de forma mais compacta como:
select cat.mate from Cat cat
As consultas podem retornar propriedades de qualquer tipo de valor, incluindo propriedades de tipo de componente:
select cat.name from DomesticCat cat where cat.name like 'fri%'
select cust.name.firstName from Customer as cust
As consultas podem retornar múltiplos objetos e/ou propriedades como uma matriz do tipo Object[]
:
select mother, offspr, mate.name from DomesticCat as mother inner join mother.mate as mate left outer join mother.kittens as offspr
Ou como um List
:
select new list(mother, offspr, mate.name) from DomesticCat as mother inner join mother.mate as mate left outer join mother.kittens as offspr
Ou - considerando que a classe Family
tenha um construtor apropriado - como um objeto Java typesafe atual:
select new Family(mother, mate, offspr) from DomesticCat as mother join mother.mate as mate left join mother.kittens as offspr
Pode-se designar alias à expressões selecionadas usando as
:
select max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n from Cat cat
Isto é bem mais útil quando usado junto com
selecione novo mapa
:
select new map( max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n ) from Cat cat
Esta consulta retorna um Mapa
de referências para valores selecionados.
As consultas HQL podem retornar o resultado de funções agregadas nas propriedades:
select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat) from Cat cat
As funções agregadas suportadas são:
avg(...), sum(...), min(...), max(...)
count(*)
count(...), count(distinct ...), count(all...)
Pode-se usar operadores aritméticos, concatenação e funções SQL reconhecidas na cláusula select:
select cat.weight + sum(kitten.weight) from Cat cat join cat.kittens kitten group by cat.id, cat.weight
select firstName||' '||initial||' '||upper(lastName) from Person
As palavras distinct
e all
podem ser usadas e têm a mesma semântica que no SQL.
select distinct cat.name from Cat cat select count(distinct cat.name), count(cat) from Cat cat
A consulta:
from Cat as cat
retorna instâncias não só de Cat
, mas também de subclasses como DomesticCat
. As consultas do Hibernate podem nomear qualquer classe Java ou interface na cláusula from
. A consulta retornará instâncias de todas as classes persistentes que extendam a determinada classe ou implemente a determinada interface. A consulta a seguir, poderia retornar todos os objetos persistentes:
from java.lang.Object o
A interface Named
pode ser implementada por várias classes persistentes:
from Named n, Named m where n.name = m.name
Note que as duas últimas consultas requerem mais de um SQL SELECT
. Isto significa que a cláusula order by
não ordena corretamente todo o resultado. Isso também significa que você não pode chamar essas consultas usando consulta.scroll()
.
A cláusula where
permite estreitar a lista de instâncias retornadas. Se não houver referência alguma, pode-se referir à propriedades pelo nome:
from Cat where name='Fritz'
Se houver uma referência, use o nome da propriedade qualificada:
from Cat as cat where cat.name='Fritz'
Isto retorna instâncias de Cat
com nome ‘Fritz’.
A seguinte consulta:
select foo from Foo foo, Bar bar where foo.startDate = bar.date
retornará todas as instâncias de Foo
, para cada um que tiver uma instância de bar
com a propriedade date
igual a propriedade startDate
de Foo
. Expressões de caminho compostas fazem da cláusula where
, extremamente poderosa. Consideremos:
from Cat cat where cat.mate.name is not null
Esta consulta traduz para uma consulta SQL com uma tabela (inner) união. Por exemplo:
from Foo foo where foo.bar.baz.customer.address.city is not null
resultaria numa consulta que necessitasse de união de quatro tabelas, no SQL.
O operador =
pode ser usado para comparar não apenas propriedades, mas também instâncias:
from Cat cat, Cat rival where cat.mate = rival.mate
select cat, mate from Cat cat, Cat mate where cat.mate = mate
The special property (lowercase) id
can be used to reference the unique identifier of an object. See Seção 15.5, “Referência à propriedade do identificador ” for more information.
from Cat as cat where cat.id = 123 from Cat as cat where cat.mate.id = 69
A segunda consulta é eficiente e não requer nenhuma união de tabelas.
As propriedades de identificadores compostas também podem ser usadas. Considere o seguinte exemplo onde Person
possui identificadores compostos que consistem de country
e medicareNumber
:
from bank.Person person where person.id.country = 'AU' and person.id.medicareNumber = 123456
from bank.Account account where account.owner.id.country = 'AU' and account.owner.id.medicareNumber = 123456
Mais uma vez, a segunda consulta não precisa de nenhuma união de tabela.
See Seção 15.5, “Referência à propriedade do identificador ” for more information regarding referencing identifier properties)
Da mesma forma, a propriedade especial class
acessa o valor discriminador da instância, no caso de persistência polimórfica. O nome de uma classe Java inclusa em uma cláusula where, será traduzida para seu valor discriminante.
from Cat cat where cat.class = DomesticCat
You can also use components or composite user types, or properties of said component types. See Seção 15.17, “Componentes” for more information.
Um tipo "any" possui as propriedades id
e class
especiais, nos permitindo expressar uma união da seguinte forma (onde AuditLog.item
é uma propriedade mapeada com
<any>
):
from AuditLog log, Payment payment where log.item.class = 'Payment' and log.item.id = payment.id
Veja que log.item.class
e payment.class
podem referir-se à valores de colunas de banco de dados completamente diferentes, na consulta acima.
As expressões permitidas na cláusula where
incluem o seguinte:
operadores matemáticos: +, -, *, /
operadores de comparação binários: =, >=, <=, <>, !=, like
operadores lógicos and, or, not
Parênteses ( )
que indica o agrupamento
in
, not in
, between
, is null
, is not null
, is empty
, is not empty
, member of
and not member of
case "simples" , case ... when ... then ... else ... end
, and "searched" case, case when ... then ... else ... end
concatenação de string ...||...
ou concat(...,...)
current_date()
, current_time()
e current_timestamp()
second(...)
, minute(...)
, hour(...)
, day(...)
, month(...)
e year(...)
qualquer função ou operador definidos pela EJB-QL 3.0: substring(), trim(), lower(), upper(), length(), locate(), abs(), sqrt(), bit_length(), mod()
coalesce()
and nullif()
str()
para converter valores numéricos ou temporais para uma string de leitura
cast(... as ...)
, onde o segundo argumento é o nome do tipo hibernate, eextract(... from ...)
se ANSI cast()
e extract()
é suportado pelo banco de dados adjacente
A função HQL index()
, que se aplicam às referências de coleçôes associadas e indexadas
As funções HQL que retornam expressões de coleções de valores: size(), minelement(), maxelement(), minindex(), maxindex()
, junto com o elemento especial, elements()
e funções de índices
que podem ser quantificadas usando some, all, exists, any, in
.
Qualquer função escalar suportada pelo banco de dados como sign()
, trunc()
, rtrim()
e sin()
Parâmetros posicionais ao estilo JDBC ?
Parâmetros nomeados :name
, :start_date
e :x1
Literais SQL 'foo'
, 69
, 6.66E+2
, '1970-01-01 10:00:01.0'
Constantes Java final estático público
ex: Color.TABBY
in
e between
podem ser usadas da seguinte maneira:
from DomesticCat cat where cat.name between 'A' and 'B'
from DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )
As formas negativas podem ser escritas conforme segue abaixo:
from DomesticCat cat where cat.name not between 'A' and 'B'
from DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )
Da mesma forma, is null
e is not null
podem ser usados para testar valores nulos.
Booleanos podem ser facilmente usados em expressões, declarando as substituições da consulta HQL, na configuração do Hibernate:
<property name="hibernate.query.substitutions" >true 1, false 0</property >
Isso irá substituir as palavras chave true
e false
pelos
literais 1
e 0
na tradução do HQL para SQL.
from Cat cat where cat.alive = true
Pode-se testar o tamanho de uma coleção com a propriedade especial size
ou a função especial size()
.
from Cat cat where cat.kittens.size > 0
from Cat cat where size(cat.kittens) > 0
Para coleções indexadas, você pode se referir aos índices máximo e mínimo, usando as funções minindex
e maxindex
. Igualmente, pode-se referir aos elementos máximo e mínimo de uma coleção de tipos básicos usando as funções minelement
e maxelement
. Por exemplo:
from Calendar cal where maxelement(cal.holidays) > current_date
from Order order where maxindex(order.items) > 100
from Order order where minelement(order.items) > 10000
As funções SQL any, some, all, exists, in
são suportadas quando passado o elemento ou o conjunto de índices de uma coleção (elements
e índices
de funções) ou o resultado de uma subconsulta (veja abaixo):
select mother from Cat as mother, Cat as kit where kit in elements(foo.kittens)
select p from NameList list, Person p where p.name = some elements(list.names)
from Cat cat where exists elements(cat.kittens)
from Player p where 3 > all elements(p.scores)
from Show show where 'fizard' in indices(show.acts)
Note que essas construções - tamanho
, elementos
, índices
, minindex
, maxindex
, minelement
, maxelement
– só podem ser usados na cláusula where do Hibernate3.
Elementos de coleções com índice (matriz, listas, mapas) podem ser referenciadas pelo índice (apenas na cláusula where):
from Order order where order.items[0].id = 1234
select person from Person person, Calendar calendar where calendar.holidays['national day'] = person.birthDay and person.nationality.calendar = calendar
select item from Item item, Order order where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11
select item from Item item, Order order where order.items[ maxindex(order.items) ] = item and order.id = 11
A expressão entre colchetes []
pode ser até uma expressão aritimética:
select item from Item item, Order order where order.items[ size(order.items) - 1 ] = item
O HQL também provê a função interna index()
para elementos de associação um-para-muitos ou coleção de valores.
select item, index(item) from Order order join order.items item where index(item) < 5
Funções escalares SQL, suportadas pelo banco de dados subjacente podem ser usadas:
from DomesticCat cat where upper(cat.name) like 'FRI%'
Se ainda não estiver totalmente convencido, pense o quão maior e menos legível poderia ser a consulta a seguir, em SQL:
select cust from Product prod, Store store inner join store.customers cust where prod.name = 'widget' and store.location.name in ( 'Melbourne', 'Sydney' ) and prod = all elements(cust.currentOrder.lineItems)
Hint: algo como:
SELECT cust.name, cust.address, cust.phone, cust.id, cust.current_order FROM customers cust, stores store, locations loc, store_customers sc, product prod WHERE prod.name = 'widget' AND store.loc_id = loc.id AND loc.name IN ( 'Melbourne', 'Sydney' ) AND sc.store_id = store.id AND sc.cust_id = cust.id AND prod.id = ALL( SELECT item.prod_id FROM line_items item, orders o WHERE item.order_id = o.id AND cust.current_order = o.id )
A lista retornada pela consulta pode ser ordenada por qualquer propriedade da classe ou componentes retornados:
from DomesticCat cat order by cat.name asc, cat.weight desc, cat.birthdate
As opções asc
ou desc
indicam ordem crescente ou decrescente, respectivamente.
Uma consulta que retorne valores agregados, podem ser agrupados por qualquer propriedade de uma classe ou componentes retornados:
select cat.color, sum(cat.weight), count(cat) from Cat cat group by cat.color
select foo.id, avg(name), max(name) from Foo foo join foo.names name group by foo.id
Uma cláusula having
também é permitida.
select cat.color, sum(cat.weight), count(cat) from Cat cat group by cat.color having cat.color in (eg.Color.TABBY, eg.Color.BLACK)
Funções SQL e funções agregadas são permitidas nas cláusulas having
e order by
, se suportadas pelo banco de dados subjacentes (ex: não no MeuSQL).
select cat from Cat cat join cat.kittens kitten group by cat.id, cat.name, cat.other, cat.properties having avg(kitten.weight) > 100 order by count(kitten) asc, sum(kitten.weight) desc
Note que, nem a cláusula group by
ou order by
podem conter expressões aritméticas. O Hibernate também não expande atualmente uma entidade agrupada, portanto você não pode escrever group by cat
caso todas as propriedades do cat
não estiverem agregadas. Você precisa listar claramente todas as propriedades não-agregadas.
Para bancos de dados que suportam subseleções, o Hibernate suporta subconsultas dentro de consultas. Uma subconsulta precisa estar entre parênteses (normalmente uma chamada de função agregada SQL). Mesmo subconsultas co-relacionadas (subconsultas que fazem referência à alias de outras consultas), são aceitas.
from Cat as fatcat where fatcat.weight > ( select avg(cat.weight) from DomesticCat cat )
from DomesticCat as cat where cat.name = some ( select name.nickName from Name as name )
from Cat as cat where not exists ( from Cat as mate where mate.mate = cat )
from DomesticCat as cat where cat.name not in ( select name.nickName from Name as name )
select cat.id, (select max(kit.weight) from cat.kitten kit) from Cat as cat
Note que HQL subconsultas podem aparecer apenas dentro de cláusulas select ou where.
Note that subqueries can also utilize row value constructor
syntax. See Seção 15.18, “Sintáxe do construtor de valores de linha” for more information.
As consultas do Hibernate, podem ser muito poderosas e complexas. De fato, o poder da linguagem de consulta é um dos pontos principais na distribuição do Hibernate. Aqui temos algumas consultas de exemplo, muito similares a consultas usadas em um projeto recente. Note que a maioria das consultas que você irá escrever, são mais simples que estas.
A consulta a seguir retorna o id de ordenar, número de ítens e o valor total do ordenar para todos os ordenar não pagos para um cliente particular e valor total mínimo dado, ordenando os resultados por valor total. Para determinar os preços, utiliza-se o catálogo atual. A consulta SQL resultante, usando tabelas ORDER
, ORDER_LINE
, PRODUCT
, CATALOG
e PRICE
, têm quatro uniões inteiras e uma subseleção (não correlacionada).
select order.id, sum(price.amount), count(item) from Order as order join order.lineItems as item join item.product as product, Catalog as catalog join catalog.prices as price where order.paid = false and order.customer = :customer and price.product = product and catalog.effectiveDate < sysdate and catalog.effectiveDate >= all ( select cat.effectiveDate from Catalog as cat where cat.effectiveDate < sysdate ) group by order having sum(price.amount) > :minAmount order by sum(price.amount) desc
Que monstro! Na verdade, na vida real, eu não sou muito afeiçoado à subconsultas, então minha consulta seria mais parecida com isto:
select order.id, sum(price.amount), count(item) from Order as order join order.lineItems as item join item.product as product, Catalog as catalog join catalog.prices as price where order.paid = false and order.customer = :customer and price.product = product and catalog = :currentCatalog group by order having sum(price.amount) > :minAmount order by sum(price.amount) desc
A próxima consulta conta o número de pagamentos em cada status, excluindo todos os pagamentos no status AWAITING_APPROVAL
, onde a mais recente mudança de status foi feita pelo usuário atual. Traduz-se para uma consulta SQL com
duas uniões inteiras e uma subseleção correlacionada, nas tabelas PAYMENT
, PAYMENT_STATUS
e PAYMENT_STATUS_CHANGE
.
select count(payment), status.name from Payment as payment join payment.currentStatus as status join payment.statusChanges as statusChange where payment.status.name < > PaymentStatus.AWAITING_APPROVAL or ( statusChange.timeStamp = ( select max(change.timeStamp) from PaymentStatusChange change where change.payment = payment ) and statusChange.user < > :currentUser ) group by status.name, status.sortOrder order by status.sortOrder
Se eu tivesse mapeado a coleção statusChanges
como um List, ao invés de um Set, a consulta teria sido muito mais simples de escrever.
select count(payment), status.name from Payment as payment join payment.currentStatus as status where payment.status.name < > PaymentStatus.AWAITING_APPROVAL or payment.statusChanges[ maxIndex(payment.statusChanges) ].user < > :currentUser group by status.name, status.sortOrder order by status.sortOrder
A próxima consulta usa a função isNull()
do Servidor MS SQL, para retornar todas as contas e pagamentos não efetuados para a organização, para aquele que o usuário atual pertencer. Traduz-se para uma consulta SQL com
três uniões inteiras, uma união externa e uma subseleção nas tabelas ACCOUNT
, PAYMENT
, PAYMENT_STATUS
, ACCOUNT_TYPE
, ORGANIZATION
e ORG_USER
.
select account, payment from Account as account left outer join account.payments as payment where :currentUser in elements(account.holder.users) and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID) order by account.type.sortOrder, account.accountNumber, payment.dueDate
Para alguns bancos de dados, precisaremos eliminar a subseleção (correlacionada).
select account, payment from Account as account join account.holder.users as user left outer join account.payments as payment where :currentUser = user and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID) order by account.type.sortOrder, account.accountNumber, payment.dueDate
HQL now supports update
, delete
and insert ... select ...
statements. See Seção 14.4, “Operações no estilo DML” for more information.
Pode-se contar o número de resultados da consulta, sem realmente retorná-los:
( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue()
Para ordenar um resultado pelo tamanho de uma coleção, use a consulta a seguir.
select usr.id, usr.name from User as usr left join usr.messages as msg group by usr.id, usr.name order by count(msg)
Se seu banco de dados suporta subseleções, pode-se colocar uma condição sobre tamanho de seleção na cláusula where da sua consulta:
from User usr where size(usr.messages) >= 1
Se seu banco de dados não suporta subseleções, use a consulta a seguir:
select usr.id, usr.name from User usr join usr.messages msg group by usr.id, usr.name having count(msg) >= 1
Com essa solução não se pode retornar um User
sem nenhuma menssagem, por causa da união inteira, a forma a seguir também é útil:
select usr.id, usr.name from User as usr left join usr.messages as msg group by usr.id, usr.name having count(msg) = 0
As propriedades de um JavaBean podem ser limitadas à parâmetros nomeados da consulta:
Query q = s.createQuery("from foo Foo as foo where foo.name=:name and foo.size=:size");
q.setProperties(fooBean); // fooBean has getName() and getSize()
List foos = q.list();
As coleções são pagináveis, usando a interface Query
com um filtro:
Query q = s.createFilter( collection, "" ); // the trivial filter
q.setMaxResults(PAGE_SIZE);
q.setFirstResult(PAGE_SIZE * pageNumber);
List page = q.list();
Os elementos da coleção podem ser ordenados ou agrupados usando um filtro de consulta:
Collection orderedCollection = s.filter( collection, "order by this.amount" );
Collection counts = s.filter( collection, "select this.type, count(this) group by this.type" );
Pode-se achar o tamanho de uma coleção sem inicializá-la:
( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue();
Os componentes podem ser usados de quase todas as formas que os tipos de valores simples são usados nas consultas HQL. Eles podem aparecer na cláusula select
:
select p.name from Person p
select p.name.first from Person p
onde a propriedade do nome da Person é um componente. Os componentes também podem ser utilizados na cláusula where
:
from Person p where p.name = :name
from Person p where p.name.first = :firstName
Os componentes também podem ser usados na cláusula order by
:
from Person p order by p.name
from Person p order by p.name.first
Outro uso comum dos componentes é nos row value constructors.
O HQL suporta o uso da sintáxe ANSI SQL row value constructor
, algumas vezes chamado de sintáxe tupla
, embora o banco de dados adjacente possa não suportar esta noção. Aqui nós geralmente nos referimos às comparações de valores múltiplos, tipicamente associada aos componentes. Considere uma entidade Person que define um componente de nome:
from Person p where p.name.first='John' and p.name.last='Jingleheimer-Schmidt'
Esta é uma sintáxe válida, embora um pouco verbosa. Seria ótimo tornar essa sintáxe um pouco mais concisa e utilizar a sintáxe row value constructor
:
from Person p where p.name=('John', 'Jingleheimer-Schmidt')
Pode também ser útil especificar isto na cláusula select
:
select p.name from Person p
Com o uso da sintáxe row value constructor
, e que pode ser de benéfico, seria quando utilizar as subconsultas que precisem comparar com os valores múltiplos:
from Cat as cat where not ( cat.name, cat.color ) in ( select cat.name, cat.color from DomesticCat cat )
Ao decidir se você quer usar esta sintáxe ou não, deve-se considerar o fato de que a consulta será dependente da ordenação das sub-propriedades do componente no metadados.
Copyright © 2004 Red Hat, Inc.