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 kittenfrom 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 kittenVocê 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.0A "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 21.1, “Estratégias de Busca ” for more information.
from Cat as cat
inner join fetch cat.mate
left join fetch cat.kittensGeralmente, 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.kittensObserve 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 mateA consulta selecionará mates (parceiros), de outros Cats. 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 offsprOu 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 offsprOu - 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 offsprPode-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 comselecione 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.weightselect 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 16.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 = 123456from bank.Account account
where account.owner.id.country = 'AU'
and account.owner.id.medicareNumber = 123456Mais uma vez, a segunda consulta não precisa de nenhuma união de tabela.
See Seção 16.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 16.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úblicoex: 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 falsepelos 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 = calendarselect 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) < 5Funçõ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) descNote 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 16.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) descQue 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) descA 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.sortOrderSe 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.sortOrderA 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.dueDatePara 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.dueDateHQL now supports update, delete and insert ... select ... statements. See Seção 15.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)
>= 1Com 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) = 0As 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.