JPA (Java Persistence API) Marcos Kalinowski (kalinowski@ic.uff.br)



Documentos relacionados
Aula 2 - Revisão de JPA (Java Persistence API)

Aula 2 - Revisão de JPA (Java Persistence API)

Persistência de Dados em Java com JPA e Toplink

Hibernate. Mapeamento Objeto-Relacional. Prof. Anselmo Cardoso Paiva Prof. Geraldo Braz Junior

Mapeamento Lógico/Relacional com JPA


Java Persistence API. Entity Entity Campos e Propriedades Entity Chaves Primárias Entity Associações

UFG - Instituto de Informática

JPA: Persistência padronizada em Java

Aula 4. Carlos Eduardo de Carvalho Dantas

JPA Passo a Passo. Henrique Eduardo M. Oliveira henrique@voffice.com.br. Globalcode Open4Education

UFG - Instituto de Informática

Hibernate. Mapeamento O/R Marcio Aguiar Ribeiro

UFG - Instituto de Informática

Padrão J2EE Data Access Object (DAO)

Persistência de dados com JPA. Hélder Antero Amaral Nunes

Persistindo dados com TopLink no NetBeans

HIBERNATE Criando um projeto em Java + Hibernate do zero

Resolvendo objeto-relacional impedance mismatch com hibernate

Auditando persistência com JPA

Módulo 03. Mapeando Associações/Relacionamentos. Raphaela Galhardo.

ALTO DESEMPENHO UTILIZANDO FRAMEWORK HIBERNATE E PADRÃO JAVA PERSISTENCE API

1 Criar uma entity a partir de uma web application que usa a Framework JavaServer Faces (JSF)

Auditoria Avançada de Persistência com Hibernate, JPA e Envers

UFG - Instituto de Informática

MAPEAMENTO OBJETO RELACIONAL: UM ESTUDO DE CASO

Hibernate Envers Easy Entity Auditing

Java Persistence Query Language JPQL

JPA Java Persistence API. Prof. Ramon Chiara

Linguagem de Consulta - SQL

SQL Linguagem de Definição de Dados. Banco de Dados Profa. Dra. Cristina Dutra de Aguiar Ciferri

DESENVOLVIMENTO DE SOFTWARE

SQL comando SELECT. SELECT [DISTINCT] <campos> FROM <tabela> [condição] [ ; ] Paulo Damico - MDK Informática Ltda.

Linguagem de Programação JAVA. Técnico em Informática Professora Michelle Nery

Uma Abordagem sobre Mapeamento Objeto Relacional com Hibernate

Exercícios de Revisão Java Básico

Capítulo 1 - Java EE 6 por alto - 1

Aula 5. Carlos Eduardo de Carvalho Dantas

Programação Java. em Ambiente Distribuído. Ênfase no Mapeamento Objeto-Relacional com JPA, EJB e Hibernate. Douglas Rocha Mendes.

UFG - Instituto de Informática

Curso PHP Aula 08. Bruno Falcão

Programação por Objectos. Java

Figura 5 - Workflow para a Fase de Projeto

PHP Programando com Orientação a Objetos

Desmistificando o Hibernate Envers em 10 passos

5 - Vetores e Matrizes Linguagem C CAPÍTULO 5 VETORES E MATRIZES

Análise de Programação

SQL - Criação de Tabelas

Especificação do Trabalho

Implementando uma Classe e Criando Objetos a partir dela

Banco de Dados. Marcio de Carvalho Victorino Exercícios SQL

Struts 2 : Projeto e Programação Editora: Ciência Moderna Autor: Antunes Budi Kurniawan Número de páginas: 600

Persistência com JPA2 e Hibernate TREINAMENTOS

JPA - Java Persistence API. Entity. Entity Campos e Propriedades Entity Chaves Primárias Entity Associações. Entity Manager

JPA - Java Persistence API. Entity. Entity Campos e Propriedades Entity Chaves Primárias Entity Associações. Entity Manager

Banco de Dados I Módulo V: Indexação em Banco de Dados. (Aulas 4) Clodis Boscarioli

Banco de Dados. Sérgio Luiz Ruivace Cerqueira

A linguagem SQL

Java Beans e Servlets

Manipulação de Banco de Dados com Java. Ms. Bruno Crestani Calegaro Maio/ 2015

Curso de Java. Acesso a banco de dados através do Hibernate. Todos os direitos reservados Klais

Java & Bancos de Dados Adaptado de Slides da Universidade Salgado de Oliveira Goiânia

SISTEMA TYR DIAGRAMAS DE CLASSE E SEQUÊNCIA Empresa: Academia Universitária

Introdução à Engenharia da Computação. Banco de Dados Professor Machado

J550 Integração com Bancos de Dados

PHP INTEGRAÇÃO COM MYSQL PARTE 1

Modelo Relacional. 2. Modelo Relacional (Lógico)

1. Domínio dos Atributos

Capítulo 8. Introdução UML

3.1 Definições Uma classe é a descrição de um tipo de objeto.

HIBERNATE EM APLICAÇÃO JAVA WEB

SQL Linguagem de Definição de Dados. Laboratório de Bases de Dados Profa. Dra. Cristina Dutra de Aguiar Ciferri

Introdução ao Paradigma Orientado a Objetos. Principais conceitos

ÍNDICE. Delphi... 3 CAPÍTULO 1 INTRODUÇÃO CAPÍTULO 2 INSTALANDO O DELPHI... 10

Banco de Dados. Um momento crucial na organização dos dados é a forma com que cadastramos estes dados, a estrutura de armazenamento que criamos.

Banco de Dados Oracle 10g: Introdução à Linguagem SQL

Criar uma aplicação JPA2 com EclipseLink e H2

Módulo 5 JPATransaction Camadas Turma Turma TurmaBC TurmaBC TurmaBC TurmaBC

Mapeamento Objeto-Relacional

Programação Orientada a Objetos (DPADF 0063)

Figura 1. A Classe Java

Banco de Dados. Profª. Ana Leda

SOP - TADS Sistemas de Arquivos Cap 4 Tanenmbaum

PROJETO PEDAGÓGICO DE CURSOS

AULA 2 INTERAÇÃO COM O BANCO DE DADOS

MANIPULANDO BANCO DE DADOS NO POSTGRESQL SEM FAZER USO DE COMANDOS SQL

SQL. Autor: Renata Viegas

Aula 1 Acesso a Banco de Dados

Prof.: Clayton Maciel Costa

Persistência de Classes em Tabelas de Banco de Dados

Etc & Tal. Volume 2 - Número 1 - Abril 2009 SBC HORIZONTES 44

Banco de Dados. Prof. Leonardo Barreto Campos 1

Android e Bancos de Dados

Disciplina de Banco de Dados Parte V

Usando PostgreSQL na Regra de Negócio de um ERP. Fabiano Machado Dias Eduardo Wolak

Tipos de dados complexos e objectos Tipos de dados estruturados e herança em SQL Herança de tabelas Matrizes e multi-conjuntos em SQL Identidade de

Como criar um EJB. Criando um projeto EJB com um cliente WEB no Eclipse

Transcrição:

JPA (Java Persistence API) (kalinowski@ic.uff.br)

Agenda Conceitos básicos do JPA Mapeamento objeto relacional utilizando JPA Utilizando JPA para a persistência na prática EntityManager JPQL (Java Persistence Query Language) 2

Agenda Conceitos básicos do JPA Mapeamento objeto relacional utilizando JPA Utilizando JPA para a persistência na prática EntityManager JPQL (Java Persistence Query Language) 3

Conceitos básicos do JPA JPA é uma abstração em cima do JDBC que torna possível ser independente do SQL Todas as classes e anotações da API JPA estão no pacote javax.persistence 4

Principais componentes do JPA ORM (Object-Relational Mapping) para a criação de objetos de domínio que podem ser persistidos (Entities) Uma API (EntityManager) para desempenhar operações de BD como Criar, Ler, Atualizar e Remover (CRUD) A linguagem de consulta de persistência Java (Java Persistence Query Language - JPQL) que permite recuperar dados com uma linguagem de consulta OO 5

O Conceito de Entidade Quando estamos mapeando objetos para um BD relacional, para persisti-los ou consultá-los o termo entidade deve ser usado Objetos são apenas mantidos em memória Entidades são objetos que são mantidas na memória durante um algum intervalo de tempo e, então persistidas no banco de dados Suportam herança, relacionamentos, etc. Desde que mapeados para o gerenciamento do JPA Uma vez persistidas, as entidades podem ser consultadas através da JPQL 6

Agenda Conceitos básicos do JPA Mapeamento objeto relacional utilizando JPA Utilizando JPA para a persistência na prática EntityManager JPQL (Java Persistence Query Language) 7

Mapeamento Objeto-Relacional O princípio do ORM é delegar a ferramentas externas (no nosso caso JPA) a tarefa de criar uma correspondência entre objetos e tabelas O mundo das classes, objetos e atributos podem, então, ser mapeados para BDs relacionais consistindo em tabelas, linhas e colunas O mapeamento proporciona uma visão orientada à objetos aos desenvolvedores que podem usar entidades em vez de tabelas de forma transparente 8

Mapeamento Objeto-Relacional Há uma diferença semântica significativa entre o modelo de classes de um projeto orientado a objetos e o modelo relacional. Assim, para que a persistência de objetos seja feita em um banco de dados relacional, é necessário proceder um mapeamento entre esses dois mundos. Diretriz: O mapeamento só deve ser visível na camada de persistência, isolando as classes de domínio do impacto da tecnologia de bancos de dados. Alternativas: Padrão DAO; Frameworks como JPA 9

Mapeamento Objeto-Relacional No mapeamento dos mundos de objetos e relacional, as seguintes questões devem ser abordadas: Mapeamento de Classes para Tabelas e de Objetos para Linhas; Mapeamento de Herança; Mapeamento de Relacionamentos entre Objetos. 10

Mapeamento de Classes para Tabelas e de Objetos para Linhas Quando não há herança, cada classe deve ser mapeada em uma tabela e cada instância da classe (objeto) em uma linha desta tabela. E as chaves primárias das Tabelas? Objetos têm identidade própria, independentemente dos valores de seus atributos. Que identificador devemos designar aos nossos objetos no banco de dados relacional? Verificar se há um atributo na classe com propriedade de identificação única e utilizá-lo, então, como chave primária. Caso não haja um atributo com tal característica, deverá ser criado um. 11

Mapeando Herança Existem três soluções razoavelmente aplicáveis para mapear a herança em um banco de dados relacional: 1) Utilizar uma tabela por classe na hierarquia, com chaves estrangeiras para a classe pai. 2) Utilizar uma tabela por classe filha na hierarquia. Cada tabela derivada para as classes concretas inclui tanto os atributos da classe quanto os de suas superclasses. Problemas? Possível redundância e inconsistência de dados. 3) Utilizar uma tabela para a classe pai com todos os atributos. As subclasses serão views da classe pai. Problemas? Possível redundância e inconsistência de dados. 12

Mapeando Relacionamentos É necessário transpor chaves entre tabelas para mapear relacionamentos. As regras válidas para o modelo relacional tem de ser aplicadas, tal como criar uma tabela adicional para mapear um relacionamento muitos-para-muitos. 13

Exemplo 14

Exemplo 15

Definição das Tabelas Alternativa 1 16

Definição das Tabelas Alternativa 2 (a princípio menos interessante) 17

Definição das Tabelas Alternativa 3 18

Exemplo 19

Definição das Tabelas 20

Exemplo 21

Definição das Tabelas 22

Mapeamento Objeto-Relacional Mas como o JPA mapeia objetos para um BD? Através de metadados! No JPA, metadados podem ser de dois tipos: Anotações: a classe é anotada com informações sobre como deve ser persistida Descritores XML: neste caso, o mapeamento é definido em um arquivo XML externo Podem ser usados em conjunto com anotações e oferecem a possibilidade de serem editados sem mudar o código Utiliza configuração por exceção Exemplo: por padrão, o nome da tabela é o mesmo da entidade, mas é configurável via metadados 23

Trabalhando com uma Entidade 24

Trabalhando com uma Entidade 25

Trabalhando com uma Entidade 26

Regras para Implementação de uma Entidade A entidade deve ser anotada com @javax.persistence.entity A anotação @javax.persistence.id deve ser usada para criar uma chave primária simples A classe entidade deve possuir um construtor sem argumentos o qual deve ser public ou protected A classe entidade não pode ser um enum ou interface, apenas class é permitido A classe entidade não deve ser final. Nenhum dos métodos ou variáveis de instância pode ser final 27

Configuração por Exceção Desde que as entidades respeitem as regras, o provedor de persistência pode fazer o mapeamento considerando algumas convenções O nome da classe é mapeado como o nome da tabela Para mudar o nome use a anotação @Table Os nomes dos atributos são mapeados como nome das colunas Para mudar o nome use a anotação @Column Para mapear os tipos de dados, as mesmas regras do JDBC são válidas Por exemplo, String mapeia para VARCHAR O tamanho do varchar tem como padrão 255 28

@Table Elementos Básicos do Mapeamento: Tabelas Pode-se definir propriedades da tabela, como seu nome Por padrão, os nomes das tabelas são criadas com letra maiúscula, assim como nome da classe Ex: @Table(name = livro") 29

Elementos Básicos do Mapeamento: Tabelas @SecondaryTable Permite que os atributos de uma Entidade (classe) possa ser distribuído entre mais de uma tabela Para várias tabelas secundárias use @SecondaryTables Exemplo: @SecondaryTables({ @SecondaryTable(name = cidade"), @SecondaryTable(name = pais") }) Para mapear os atributos para as diferentes tabelas use: @Column(table = cidade") private String cidade; Colunas que não especificarem a sua tabela serão mapeadas para a tabela primária Importante: considere questões de desempenho se optar por utilizar tabelas secundárias 30

@Id Elementos Básicos do Mapeamento: Chaves Primárias Define uma chave primária Pode ser dos seguintes tipos: Tipos primitivos: byte, int, short, long e char Classes wrapper : Byte, Integer, Short, Long, Character Strings, números e datas: String, BigInteger e Date 31

Elementos Básicos do Mapeamento: @GeneratedValue Define que a coluna ter um valor gerado automaticamente Possui quatro valores: Chaves Primárias SEQUENCE e IDENTITY: define uma coluna sequence ou identity, respectivamente. TABLE: instrui o provedor de persistência a usar uma tabela para armazenar a semente da sequencia. É criada uma tabela com duas colunas - uma contendo o nome (arbitrário) e a outra o valor AUTO: a escolha da estratégia para geração do chave é feita automaticamente Ex: @GeneratedValue(strategy = GenerationType.AUTO) 32

Elementos Básicos do Mapeamento: Atributos O JPA permite o mapeamento dos seguintes tipos: Tipos primitivos (int, double, etc.) e as classes wrapper Array de bytes e caracteres String, númerico (BigInteger) e os temporais (Date, Calendar, Time e Timestamp) Tipos enumerados e definidos pelo usuário (atributos cujo o tipo seja uma classe definida pelo desenvolvedor) Requer um mapeamento entre entidades 33

@Basic Elementos Básicos do Mapeamento: Atributos É o tipo de mapeamento mais simples, definindo (através de seus parâmetros): optional: indica se o atributo é obrigatório ou não (se pode ser null na base de dados) fetch: indica se o atributo deve ser carregado quando a aplicação utilize o valor através da chamada get (LAZY) ou se carrega-o no momento que o objeto for criado (EAGER) Exemplo: @Basic(optional=true, fetch=fetchtype.lazy) private String descricao; 34

@Column Elementos Básicos do Mapeamento: Atributos Define grande parte das propriedades comuns à colunas em banco de dados: Ex: name, length, unique etc. Algumas outras anotações: @Temporal Usada para definir datas @Transient Permite que um atributo não seja persistido Lembre-se ainda: anotações de mapeamento de atributo também podem ser usadas no método get 35

Elementos Básicos do Mapeamento: Relacionamentos (associações) No paradigma OO, as associações se resumem as seguintes formas: Unidirecional Bidirecional Com cardinalidade 36

Elementos Básicos do Mapeamento: Relacionamentos (associações) Desta forma, temos as seguintes combinações: Cardnalidade um para um um para um um para muitos um para muitos/muitos para um muitos para um muitos para muitos muitos para muitos Direcionamento Unidirecional Bidirecional Unidirecional Bidirecional Unidirecional Unidirecional Bidirecional Usaremos as seguintes notações para mapear estes relacionamentos: @OneToOne, @OneToMany, @ManyToOne, or @ManyToMany 37

Elementos Básicos do Mapeamento: Relacionamentos (associações) No paradigma OO, o direcionamento define qual classe enxerga qual Em resumo, significa qual tem um atributo de referência para qual Em um relacionamento bidirecional ambas se referem No modelo entidade-relacionamento, existe uma decisão a mais para um relacionamento bidirecional: Quem (qual tabela) fica com a informação de relacionamento (chave estrangeira)? 38

Elementos Básicos do Mapeamento: Relacionamentos (associações um para um) Mapeando um relacionamento um para um bidirecional anotações usadas: @OneToOne Indica um relacionamento um para um Só é necessária no relacionamento bidirecional para indicar quem mapeia informações de relacionamento Pode ser usado opcionalmente para definir propriedades de cascade, fetch, dentre outras @JoinColumn Elemento opcional que permite definir informações sobre a chave estrangeira (e.g., nome da coluna da chave estrageira) 39

Elementos Básicos do Mapeamento: Relacionamentos (associações um para um) 40

Elementos Básicos do Mapeamento: Relacionamentos (associações um para muitos) O relacionamento um para muitos unidirecional também pode ser mapeado por convenção Basta, para isto, que o tipo da lista seja uma @Entity Opcionalmente pode-se usar @JoinColumn para definições adicionais 41

Elementos Básicos do Mapeamento: Relacionamentos (associações um para muitos) Relacionamentos um para muitos bidirecionais são análogos ao um para um, fazendo o uso de @OneToMany (no lugar de @OneToOne) No relacionamento muitos para muitos bidirecional, como em todo relacionamento bidirecional, deve-se definir quem é o dono do relacionamento Para isto, usa-se o mappedby do @ManyToMany A tabela de mapeamento pode ser configurada com @JoinTable Esta anotação também pode ser usada no @OneToMany quando existir uma tabela de relacionamento 42

Elementos Básicos do Mapeamento: Relacionamentos (associações um para muitos) Repare que @JoinTable fica na entidade dona do relacionamento, ou seja, a que não possui um atributo mapeada por outra 43

Um pequeno parênteses: ordenando o mapeamento 44

Elementos Básicos do Mapeamento: Relacionamentos (herança) Existem três estratégias para mapeamento de herança como sempre existe uma adotada por convenção: Uma única tabela por hierarquia (SINGLE_TABLE): a soma dos atributos é distribuída em uma tabela (estratégia padrão) Joined-subclass (JOINED): nesta abordagem, cada entidade da hierarquia, concreta ou abstrata, é mapeada em uma tabela diferente Uma tabela por classe concreta (TABLE_PER_CLASS): esta estratégia mapeia cada entidade concreta para uma tabela separada 45

Elementos Básicos do Mapeamento: Relacionamentos (herança) Algumas anotações (opcionais): @Inheritance Define a estratégia de mapeamento de herança @DiscriminatorColumn Define o nome da coluna que identifica o tipo ao qual um determinado registro pertence @DiscriminatorValue Define o valor para o tipo da entidade na qual a anotação é utilizada 46

Elementos Básicos do Mapeamento: Relacionamentos (herança) - Exemplo 47

Exercício (Atividade Prática) Defina Entidades JPA para o seguinte modelo: 48

Agenda Conceitos básicos do JPA Mapeamento objeto relacional utilizando JPA Utilizando JPA para a persistência na prática EntityManager JPQL (Java Persistence Query Language) 49

Utilizando JPA para a Persistência na Prática O elemento central da manipulação e consulta da base de dados é feita pela API da classe EntityManager Provê API para criação, remoção, busca e sincronização dos objetos com o banco de dados Além disto, permite a execução de consultas JPQL As consultas JPQL assemelham-se com a SQL, mas operam sobre objetos utilizando, por exemplo, a notação de ponto (.) dentro das consultas Exercício: verificar a documentação da API da classe EntityManager http://docs.oracle.com/javaee/7/api/javax/persistence/entitymanager.html 50

Executando uma Consulta Simples Buscando pela chave primária @PersistenceContext Private EntityManager em; Book book = em.find(book.class, id); Note que o código acima não possui nenhuma referência a SQL, JPQL ou JDBC A classe EntityManager faz tudo isto por debaixo dos panos 51

Obtendo um EntityManager Existem duas formas de se obter e manipular um EntityManager Gerenciado pela Aplicação A aplicação obtém o EntityManager por meio de uma factory e também é responsável por gerenciar as transações e recursos (begin(), commit(), close() etc). Gerenciado pelo Container Em um ambiente gerenciado pelo container é possível fazer com que o EntityManager seja injetado em um EJB, por exemplo. 52

Exemplo: Persistindo uma Entidade com um EntityManager Gerenciado pelo Container @Stateless public class LivroBean { @PersistenceContext private EntityManager em; public void crialivro() { Livro livro = new Livro(); livro.settitulo("o Guia do Mochileiro das Galáxias"); livro.setpreco(38.5f); livro.setdescricao("humor e ficção científica"); livro.setnumpaginas(380); em.persist(livro); } Como pode ser visto no exemplo acima, em um ambiente gerenciado, o EntityManager não precisa ser instanciado nem ter os seus recursos e transação manipulados 53

O Contexto de Persistência Independentemente se o EntityManager é gerenciado pelo container ou pela aplicação, ele sempre está atrelado a um contexto de persistência. O contexto de persistência pode ser entendido como um cache. Toda entidade manipulada pelo EntityManager estará neste contexto evitando chamadas desnecessárias ao banco de dados. Exemplos: Quando uma entidade é recuperada através da chave primária com o método find(), o EntityManager primeiro verifica se aquele objeto já não está naquele contexto Quando o método persist() é invocado o EntityManager coloca a entidade persistida no contexto de persistência 54

O Contexto de Persistência Todo EntityManager esta ligado a uma unidade de persistência definida no arquivo persistence.xml pelo elemento <persistence-unit/> Neste elemento são definidas todas as classes que podem fazer parte de um contexto de persistência Além disto, define como as transações são manipuladas transaction-type="resource_local " para EntityManager gerenciados pela aplicação transaction-type= JTA" para EntityManagers gerenciados pelo container O escopo do contexto de persistência depende do tipo da transação utilizada pelo EntityManager, ou seja, como é gerenciado: Gerenciado pela aplicação Mantém-se enquanto o método close() do EntityManager não for chamado Gerenciado pelo container Mantém-se enquanto a transação JTA for mantida. O que normalmente significa enquanto o EJB for mantido pelo container 55

EntityManager: Buscando pelo ID Existem duas formas de buscar pelo ID Com o find() Livro livro = em.find(livro.class, 123L); if(livro!= null) { //processa o objeto } Com getreference() try { Livro livro = em.getreference(livro.class, 123L); //processa o objeto } catch (EntityNotFoundException e) { //Entidade não encontrada } Além das diferenças visíveis na forma de recuperar uma entidade, o objeto retornado por getreference() tem suas propriedades recuperadas tardiamente (lazy fetched) Dica: se for apenas fazer set no objeto, use getreference() 56

EntityManager: Removendo uma Entidade Usa-se o método remove et.begin(); em.remove(livro); et.commit(); Mas como lidar com os objetos órfãos? O JPA oferece um recurso para relacionamentos @OneToOne ou @OneToMany, desde que a entidade órfão (Capa) seja referenciada por apenas uma entidade (Livro) @OneToOne(orphanRemoval=true) private Capa capa; 57

EntityManager: Atualizando uma Entidade Gerenciada Para atualizar uma entidade gerenciada basta chamar o método persist() et.begin(); em.persist(livro); et.commit(); livro.settitulo( Novo Título ) et.begin(); em.persist(livro); et.commit(); 58

EntityManager: Cascateando Eventos Por padrão, os métodos persist() e remove() trabalham apenas com a entidade passada como parâmetro Para fazer com que as entidades relacionadas também sejam persistidas ou removidas é necessário fazer os eventos em cascata et.begin(); em.persist(livro); em.persist(capa); et.commit(); Para que capa seja persistida junto com livro sem a necessidade de persistí-los individualmente o cascade por ser usado É uma opção disponível nas diferentes anotações de relacionamento: @OneToOne, @OneToMany, @ManyToOne e @ManyToMany @OneToOne (cascade = {CascadeType.PERSIST, CascadeType.REMOVE}) private Capa capa; O código ficaria desta forma: et.begin(); em.persist(livro); et.commit(); 59

O Ciclo de Vida das Entidades em Detalhe 60

Callbacks 61

Agenda Conceitos básicos do JPA Mapeamento objeto relacional utilizando JPA Utilizando JPA para a persistência na prática EntityManager JPQL (Java Persistence Query Language) 62

JPQL: Java Persistence Query Language JPQL é uma linguagem de consulta a entidades, independente da implementação de banco de dados usada É uma linguagem fortemente baseada no SQL, mas tem sintaxe mais próxima da orientação a objetos Notação minhaclasse.meuatributo Para executar uma consulta JPQL, o JPA a transforma em SQL e realiza chamadas JDBC ao banco de dados Exemplo de uma consulta simples: SELECT l FROM Livro l WHERE l.titulo = Guia do Mochileiro das Galáxias 63

A Sintaxe do Comando SELECT Como quase todos os comandos JPQL a sintaxe do comando SELECT é idêntica ao SQL SELECT <select expression> FROM <from clause> [WHERE <conditional expression>] [ORDER BY <order by clause>] [GROUP BY <group by clause>] [HAVING <having clause>] 64

INSERT, UPDATE e DELETE O JPQL não possui o comando INSERT Os comandos UPDATE e DELETE devem ser usados apenas para atualizações em lote Exemplos: DELETE FROM Livro l WHERE l.preco < 10 UPDATE Livro l SET l.descricao = PROMOÇÃO WHERE l.preco < 10 65

Consultas Como integrar as consultas vistas anteriormente a sua aplicação? O JPA oferece 3 tipos de consultas que podem ser usadas no código Dynamic queries: é o formato mais simples de consulta, consistindo de uma consulta JPQL definida em tempo de execução Named queries: são estáticas e imutáveis Native queries: útil para executar consultas SQL nativas no lugar de JPQL 66

Consultas O EntityManager é a classe responsável por fornecer consultas (classes do tipo Query) Método Descrição Query createquery(string jpqlstring) Query createnamedquery(string name) Query createnativequery(string sqlstring, Class resultclass) Cria uma instância de Query para executar consultas dinâmicas Cria uma instância de Query para executar uma consulta nomeada Cria uma instância de Query para executar uma consulta SQL nativa passando a classe com os resultados resperados 67

A API da classe Query Os métodos mais usados são para executar uma query, podendo ser de três tipos Queries do tipo SELECT O método getresultlist() executa a consulta e retorna uma lista de resultados O método getsingleresult() executa a consulta e retorna um resultado único Para queries do tipo UPDATE e DELETE utiliza-se o método executeupdate() 68

Consultas Dinâmicas String jpqlquery = "SELECT l FROM Livro l"; if (algumcriterio) jpqlquery += " where l.preco < :pco"; query = em.createquery(jpqlquery); query.setparameter("pco", 10.0); List<Livro> livros = query.getresultlist(); É importante observar que consultas JPQL são traduzidas, em tempo de execução, para SQL usando metadados do mapeamento ORM. Isto pode ser alvo de problemas de desempenho, que pode ser resolvido por meio do uso de consultas nomeadas (estáticas e imutáveis) 69

Consultas Nomeadas Não são flexíveis como as consultas dinâmicas, pois não podem ser montadas em tempo de execução Mas são mais eficientes, em termos de desempenho, já que são traduzidas uma vez, quando a aplicação é iniciada em vez de toda vez que a consulta é executada @Entity @NamedQueries({ @NamedQuery(name = "buscatodos", query="select l from Livro l"), @NamedQuery(name = "buscapromocao", query = "select l from Livro l where l.preco < :pco") }) public class Customer { // } 70

Consultas Nomeadas Buscando todos Query query = em.createnamedquery("buscatodos"); List<Livro> livros = query.getresultlist(); Buscando três promoções Query query = em.createnamedquery("buscapromocao"); query.setparameter("pco", 10.0); query.setmaxresults(3); List<Livro> livros = query.getresultlist(); P.S: O nome da consulta deve ser único (independente da entidade que a contém) 71

Consultas Nativas Consultas nativas podem ser dinâmicas Query query = em.createnativequery("select * FROM t_livro", Livro.class); List<Livro> livros = query.getresultlist(); Ou nomeadas (estáticas) @Entity @NamedNativeQuery(name = buscatodos", query="select * from t_livro") @Table(name = "t_livro") public class Livro { // } 72

Agenda Conceitos básicos do JPA Mapeamento objeto relacional utilizando JPA Utilizando JPA para a persistência na prática EntityManager JPQL (Java Persistence Query Language) 73

Exercícios Injetar um EntityManager no EJB com agendamento criado em exercício anterior e fazer com que ele periodicamente: Crie e persista uma entidade Tempo (bastam dois campos na Tabela, id e tempoatual). Estender seu próprio projeto, transformando seus objetos de domínio em entidades persistentes JPA. 74

Exemplo Injetando um EntityManager em um EJB com agendamento para persistir informações de Livros e Autores (@ManyToMany): Três Métodos PersisteLivro Executa de 10 em 10 segundos e sorteia um livro a ser persistido. ListaLivros Executa de de 30 em 30 segundos e lista todos os livros cadastrados no banco de dados. ApagaLivro Executa de 20 em 20 segundos, sorteia um dos livros cadastrados no banco e o apaga. 75

Estrutura Alvo 76

Criando o Banco de Dados 77

Criando as Classes de Entidade (JPA) 78

@Entity @NamedQueries({ @NamedQuery(name = "findallbooks", query = "select b from Book b"), @NamedQuery(name = "findbooksbygenre", query = "select b from Book b where b.genre = :genre") }) public class Book implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; // @Column(unique=true, nullable=false) private String isbn; private String title; @ManyToMany (cascade = {CascadeType.PERSIST, CascadeType.REMOVE}) private List<Author> authors; private String genre; @Temporal(TemporalType.TIMESTAMP) // opções DATE, TIME e TIMESTAMP private Date creationdate; public Book() { } public Book(String isbn, String title, List<Author> authors, String genre) { this.isbn = isbn; this.title = title; this.authors = authors; this.genre = genre; this.creationdate = new Date(); } } // getters e setters 79

@Entity public class Author implements Serializable{ @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; private String firstname; private String lastname; public Author() { } public Author(String firstname, String lastname) { this.firstname = firstname; this.lastname = lastname; } } public String getcitationstring(){ return lastname + ", " + firstname; } 80

O persistence.xml <?xml version="1.0" encoding="utf-8"?> <persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/xmlschem xsi:schemalocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> <persistence-unit name="enterpriseapplicationexemplopersistencia-ejbpu" transaction-type="jta"> <jta-data-source>biblioteca</jta-data-source> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties> <property name="javax.persistence.schema-generation.database.action" value="create-or-extend-tables"/> </properties> </persistence-unit> </persistence> 81

O glassfish-resources.xml <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd"> <resources> <jdbc-connection-pool... name="derby_net_biblioteca_pool...> <property name="servername" value="localhost"/> <property name="portnumber" value="1527"/> <property name="databasename" value="biblioteca"/> <property name="user" value="root"/> <property name="password" value="root"/> <property name="url" value="jdbc:derby://localhost:1527/biblioteca"/> <property name="driverclass" value="org.apache.derby.jdbc.clientdriver"/> </jdbc-connection-pool> <jdbc-resource enabled="true" jndi-name="biblioteca" object-type="user" pool-name="derby_net_biblioteca_pool"/> </resources> 82

Criando o TimerSessionBean 83

Criando o TimerSessionBean @Stateless @LocalBean public class TimerBookManager { @PersistenceContext private EntityManager em; Injeção do EntityManager // Aqui entram os três métodos } 84

Método que executa de 10 em 10 segundos e sorteia um livro a ser persistido. @Schedule(dayOfWeek = "Mon-Fri", month = "*", hour = "9-22", dayofmonth = "*", year = "*", minute = "*", second = "*/10") public void persistelivro() { List<Book> books = new ArrayList(); // Criando um livro e adicionando na lista de livros List<Author> authors = new ArrayList(); Author author = new Author ("Guilherme", "Travassos"); authors.add(author); author = new Author ("Marcos", "Kalinowski"); authors.add(author); Book b = new Book("978-85-99334-75-1", "imps 2013 : evidências sobre o desempenho das empresas que adotaram o modelo MPS-SW", authors, "Científico"); books.add(b); // Mais exemplos de livros... //Sorteando o livro que será adicionado no banco Random rn = new Random(); int chosenbook = Math.abs(rn.nextInt())%books.size(); } b = books.get(chosenbook); System.out.println("Adicionando um livro " + b.tostring()); em.persist(b); 85

Método que executa de de 30 em 30 segundos e lista todos os livros cadastrados no banco de dados. @Schedule(dayOfWeek = "Mon-Fri", month = "*", hour = "9-22", dayofmonth = "*", year = "*", minute = "*", second = "*/30") public void listalivros() { //Pegando todos os livros do banco Query query = em.createnamedquery("findallbooks"); List<Book> books = query.getresultlist(); } //Listagem dos livros System.out.println("Listagem dos livros técnicos cadastrados no Banco: "); for (Book book: books){ System.out.println(book.toString()); } 86

Método que executa de 20 em 20 segundos, sorteia um dos livros cadastrados no banco e o apaga. @Schedule(dayOfWeek = "Mon-Fri", month = "*", hour = "9-22", dayofmonth = "*", year = "*", minute = "*", second = "*/20") public void apagalivro() { //Pegando todos os livros do banco Query query = em.createnamedquery("findallbooks"); List<Book> books = query.getresultlist(); //Escolhendo um livro aleatorio Random rn = new Random(); int chosenbook = Math.abs(rn.nextInt())%books.size(); Book book = books.get(chosenbook); } //Removendo ele do banco System.out.println("Removendo um livro " + book.tostring()); em.remove((book) books.get(chosenbook)); 87

Rodando o Exemplo 88

Rodando o Exemplo Saída Esperada: 89

Banco de dados e registros criados: Rodando o Exemplo 90

Leituras Sugeridas Java EE 7 Tutorial, Eric Jendrock, Ricardo Cervera-Navarro, Ian Evans, Kim Haase, William Markito Part VIII Persistence Java EE 7: The Big Picture, Danny Coward Capítulo 12, Modern Memories: The Java Persistence API 91

JPA (Java Persistence API) (kalinowski@ic.uff.br)