Consultas com JPAQL
Utilizando JPA podemos também adicionar consultas personalizadas, para criação das consultas utilizamos a Java Persistence API Query Language (JPAQL) que é uma linguagem muito similar ao Structured Query Language (SQL) com a diferença que é mais voltado para orientação a objetos, onde facilita a navegação pelos objetos.
Nesse exemplo vamos abordar o seguinte cenário, empréstimo de livros para os clientes da biblioteca, temos as seguintes tabelas:
Script do banco de dados:
CREATE TABLE Livro (
id number(5) NOT NULL,
titulo varchar2(200) NOT NULL,
autor varchar2(200) NOT NULL,
isbn varchar2(20) NOT NULL,
paginas number(5) NOT NULL,
PRIMARY KEY(id)
);
CREATE TABLE Cliente (
id number(5) NOT NULL,
nome varchar2(200) NOT NULL,
cpf varchar2(14) NOT NULL,
telefone varchar2(9) NOT NULL,
PRIMARY KEY(id)
);
CREATE TABLE Emprestimo (
id number(5) NOT NULL,
livro_id number(5) NOT NULL,
cliente_id number(5) NOT NULL,
dataEmprestimo date NOT NULL,
dataDevolucao date,
PRIMARY KEY(id)
);
INSERT INTO Livro (id, titulo, autor, isbn, paginas)
VALUES (1, 'Almoçando com Java', 'Sakurai',
'111-11-1111-111-1', 325);
INSERT INTO Livro (id, titulo, autor, isbn, paginas)
VALUES (2, 'Classes Java em fila indiana', 'Cristiano',
'222-22-2222-222-2', 120);
INSERT INTO Livro (id, titulo, autor, isbn, paginas)
VALUES (3, 'Java em todo lugar', 'Sakurai',
'333-33-3333-333-3', 543);
INSERT INTO Livro (id, titulo, autor, isbn, paginas)
VALUES (4, 'Viajando no Java', 'Cristiano',
'444-44-4444-444-4', 210);
INSERT INTO Cliente (id, nome, cpf, telefone)
VALUES (1, 'Marcelo', '333.333.333-33', '9999-8888');
INSERT INTO Cliente (id, nome, cpf, telefone)
VALUES (2, 'Ana', '222.222.222-22', '7777-6666');
Utilizando o EJB-QL podemos criar diversas formas de consultas, onde podemos especificar as projeções, associações, restrições e outros. Exemplos de consultas:
Consultar todos os empréstimos:
SELECT e
FROM Emprestimo e
Consultar a quantidade de empréstimo por livro:
SELECT count(e)
FROM Emprestimo e
WHERE e.livro.id = :id
Consultar os empréstimos por titulo do livro:
SELECT e
FROM Emprestimo e, Livro l
WHERE e.livro.id = l.id
AND l.titulo LIKE :titulo
As consultas podem ser criadas junto com as entidades:
package pbc.jpa.exemplo.modelo;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
/**
* Classe utilizada para representar o emprestimo
* de um livro para um cliente.
*/
@NamedQueries({
@NamedQuery(name = "Emprestimo.consultarTodos",
query= "SELECT e FROM Emprestimo e"),
@NamedQuery(name = "Emprestimo.qtdEmprestimosPorLivro",
query = " SELECT count(e) " +
" FROM Emprestimo e " +
" WHERE e.livro.id = :id "),
@NamedQuery(name = "Emprestimo.consultarTodosPorTituloLivro",
query = " SELECT e " +
" FROM Emprestimo e, Livro l " +
" WHERE e.livro.id = l.id " +
" AND l.titulo LIKE :titulo ")
})
@Entity
public class Emprestimo implements Serializable {
private static final long serialVersionUID
= 7516813189218268079L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne(cascade=CascadeType.REFRESH, fetch=FetchType.EAGER)
private Livro livro;
@ManyToOne(cascade=CascadeType.REFRESH, fetch=FetchType.EAGER)
private Cliente cliente;
@Temporal(TemporalType.DATE)
private Date dataEmprestimo;
@Temporal(TemporalType.DATE)
private Date dataDevolucao;
public Cliente getCliente() { return cliente; }
public void setCliente(Cliente cliente) {
this.cliente = cliente;
}
public Date getDataDevolucao() { return dataDevolucao; }
public void setDataDevolucao(Date dataDevolucao) {
this.dataDevolucao = dataDevolucao;
}
public Date getDataEmprestimo() { return dataEmprestimo; }
public void setDataEmprestimo(Date dataEmprestimo) {
this.dataEmprestimo = dataEmprestimo;
}
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public Livro getLivro() { return livro; }
public void setLivro(Livro livro) { this.livro = livro; }
}