EJB: Query Language
Introdução
- EJB QL = Enterprise JavaBeans Query Language
- Define queries para os métodos "finder" e "select" ao usar um
Entity Bean com Container-Managed-Persistence (CMP)
- É um subconjunto de SQL92 com algumas extensões para navegar nos relacionamentos
definidos no esquema abstrato do bean
- EJB QL queries são definidos no Deployment Descriptor do bean
- Tipicamente, uma ferramenta traduz isso para o SQL do BD final
- Resultado: transportabilidade
Terminologia
- Esquema abstrato
- A parte do Deployment Descriptor do entity bean que define os campos persistentes e de
relacionamento do bean
- Há um esquema abstrato para cada entity bean com CMP
- Nome do esquema abstrato
- Um nome lógico referenciado em queries EJB QL
- Tipo do esquema abstrato
- Todas as expressões EJB QL possuem um tipo resultante
- Se a expressão for um nome do esquema abstrato, seu tipo default é a interface home
local do entity bean para o qual o nome do esquema abstrato é definido
- Navegação
- Atravessar os relacionamentos numa expressão EJB QL
- O operador de navegação é o ponto
- Path expression
- Uma expressão que navega até um entity bean relacionado
- Campo persistente
- Um campo virtual de um entity bean com CMP, armazenado num BD
- Campo de relacionamento
- Um campo virtual de um entity bean com CMP
- Identifica um entity bean relacionado
Sintaxe Simplificada
- A sintaxe geral de um query:
- select_clause from_clause [where_clause]
- A cláusula SELECT define os tipos de objetos ou valores retornados pelo query
- O tipo de retorno pode ser:
- Interface local
- Interface remota
- Campo persistente
- A cláusula FROM define o escopo do query pela declaração de variáveis de
identificação que podem ser referenciadas nas cláusulas SELECT e WHERE
- Uma variável de identificação representa um dos seguintes:
- O nome do esquema abstrato
- Um membro de uma coleção (do lado "muitos" de um relacionamento
"um-para-muitos")
- A cláusula WHERE é uma expressão condicional que restringe os objetos ou valores
retornados pelo query
Exemplos
Queries simples de "finder" methods
Exemplo 1
SELECT OBJECT(p)
FROM Player p
- Retorna todos os jogadores
- Associado ao método findall()
- A cláusula FROM declara uma variável de identificação p
- Também poderia ser "FROM Player AS p"
- O elemento "Player" é o nome do esquema abstrato do entity bean PlayerEJB
- Este bean define findall() na interface LocalPlayerHome, os objetos retornados pelo
query têm este tipo (LocalPlayerHome)
Exemplo 2
SELECT DISTINCT OBJECT(p)
FROM Player p
WHERE p.position = ?1
- Retorna os jogadores com a posição especificada no parâmetro do método
- Associado ao método findByPosition(String position)
- Numa cláusula SELECT, a palavra OBJECT deve estar antes de uma variável de
identificação tal como p
- A palavra DISTINCT elimina valores duplicados
- A cláusula WHERE restringe os jogadores retornados através da verificação de suas
posições, um campo persistente
- O elemento ?1 significa o parâmetro do método findByPosition
Exemplo 3
SELECT DISTINCT OBJECT(p)
FROM Player p
WHERE p.position = ?1 AND p.name = ?2
- Retorna os jogadores com posição e nome especificados
- Método: findByPositionAndName(String position, String name)
- ?1 é o primeiro parâmetro, ?2 é o segundo, ...
Queries de "finder" methods que navegam para beans relacionados
Exemplo 4
SELECT DISTINCT OBJECT(p)
FROM Player p, IN (p.teams) AS t
WHERE t.city = ?1
- Retorna os jogadores cujos times são da cidade especificada
- Método: findByCity(String city)
- A cláusula FROM declara duas variáveis de identificação: p e t
- A variável p representa o entity bean PlayerEJB e a variável t representa os entity
beans TeamEJB relacionados
- A declaração de t referencia a variável p
- A palavra IN significa que "teams" é uma coleção de beans relacionados
- A expressão p.teams navega de um bean PlayerEJB para seus beans TeamEJB relacionados
- O ponto é o operador de navegação
- Na cláusula WHERE, o ponto antes de "city" é um delimitador e não um
navegador de operação
- Expressões podem navegar para campos de relacionamento (beans relacionados) mas não
para campos persistentes
- Para acessar um campo persistente, uma expressão usa o ponto como delimitador
Exemplo 5
SELECT DISTINCT OBJECT(p)
FROM Player p, IN (p.teams) AS t
WHERE t.league = ?1
- Retorna os jogadores da liga (divisão) indicada
- Método: findByLeague(LocalLeague league)
- As expressões deste query navegam em dois relacionamentos
- A expressão p.team navega o relacionamento PlayerEJB-TeamEJB
- A expressão t.league navega o relacionamento TeamEJB-LeagueEJB
- Neste exemplo, o parâmetro é um objeto (uma liga) de tipo da interface
LocalLeague
- Este tipo casa com t.league na cláusula WHERE
Exemplo 6
SELECT DISTINCT OBJECT(p)
FROM Player p, IN (p.teams) AS t
WHERE t.league.sport = ?1
- Retorna os jogadores do esporte especificado
- Método: findBySport(String sport)
- O campo persistente "sport" pertence ao bean LeagueEJB
- Para chegar a este campo, o query deve primeiro navegar do bean PlayerEJB até o bean
TeamEJB (p.teams) e depois do bean TeamEJB até o bean LeagueEJB (t.league)
- Já que o campo de relacionamento "league" não é uma coleção, podemos
seguir adiante e pedir o campo sport: t.league.sport
Queries de "finder" methods com outras expressões condicionais
- Cada cláusula WHERE deve especificar uma expressão condicional
- Há vários tipos de expressões condicionais
- Nos exemplos anteriores, testamos a igualdade
- Veremos outros exemplos agora
Exemplo 7
SELECT OBJECT(p)
FROM Player p
WHERE p.teams IS EMPTY
- Retorna todos os jogadores que não estão num time
- Método: findNotOnTeam()
- O campo de relacionamento "teams" do bean PlayerEJB é uma coleção
- Se um jogador não pertencer a um time, então a coleção de times está vazia
Exemplo 8
SELECT DISTINCT OBJECT(p)
FROM Player p
WHERE p.salary BETWEEN ?1 AND ?2
- Retorna os jogadores com salário na faixa indicada
- Método: findBySalaryRange(double low, double high)
- A expressão BETWEEN é equivalente a:
p.salary >= ?1 AND p.salary <= ?2
Exemplo 9
SELECT DISTINCT OBJECT(p1)
FROM Player p1, Player p2
WHERE p1.salary > p2.salary AND p2.name = ?1
- Retorna todos os jogadores com salário maior que o do jogador com nome dado
- Método: findByHigherSalary(String name)
- A cláusula FROM declara duas variáveis de identificação p1 e p2 do mesmo tipo
(Player)
- Precisamos de 2 variáveis porque queremos comprar o salário de p1 com o salário de p2
Queries "select"
Exemplo 10
SELECT DISTINCT t.league
FROM Player p, IN (p.teams) AS t
WHERE p = ?1
- Retorna as ligas às quais o jogador especificado pertence
- Método "select": ejbSelectLeagues(LocalPlayer player)
- O tipo de retorno é o tipo de esquema abstrato do entity bean LeagueEJB
- Este esquema mapeia para a interface LocalLeagueHome
- Já que t.league não é uma variável de identificação, a palavra OBJECT é omitida
- Já sabemos que t.league é um object, não precisa dizer
- Quando usamos uma variável como p, temos que dizer se é object ou não
Exemplo 11
SELECT DISTINCT t.league.sport
FROM Player p, IN (p.teams) AS t
WHERE p = ?1
- Retorna os esportes dos quais um jogador especificado participa
- Método "select": ejbSelectSports(LocalPlayer player)
- Este query retorna um campo persistente do bean LeagueEJB
ejbql programa