Java Persistence API (JPA)

Mapeamento Objeto Relacional

LPOO 2 - Java


Prof. Rodrigo Noll - IFRS Canoas



Versão para impressão

Persistência em Java

Persistência

Persistência de dados é o termo que se refere ao armazenamento de informações em arquivo, memória ou banco de dados.

API de Acesso - JDBC

  • Conjunto de classes que permitem conexão, consultas e atualizações sobre uma base de dados
  • Manipula banco de dados relacionais
  • Utiliza SQL como linguagem para manipulação de dados
  • Dados retornam no formato de Strings e números, que devem ser mapeados em atributos de objetos
  • Hard coded-SQL

JDBC

  • Execução de comandos SQL (Statement)
  • Execução de comandos SQL parametrizados (PreparedStatement)
  • Execução de stored procedures (CallableStatement)
  • Controle de transações (commit e rollback)
  • Result Sets
  • BLOBS e CLOBS (Binary Large Object, Character Large Object)
  • Metadata

Uso do JDBC

  1. DriverManager
  2. Driver
  3. Connection
  4. Statement
  5. Resultset

DriveManager


String url =  "jdbc:oracle:thin:username/password@localhost:1521:xe";
Class.forName("oracle.jdbc.driver.OracleDriver");

Properties p = new Properties();
p.put(“autocommit”,”true”);
p.put(“create”,”true”);
try {
    Connection connection = DriverManager.getConnection(url,p);
    //executa as declarações SQL
} catch (SQLException e){
     e.printStackTrace();
}
finally {
    if ( ! conn.isClosed() )
        conn.close();
}
                

Statements

  • createStatement() : Retorna um Statement;
  • prepareStatement() : Retorna um PreparedStatement ( Statement pré-compilado que trabalha com variáveis de ligação - bind);
  • prepareCall() : Utilizado para manipulação de Stored Procedures.


  • executeQuery() - Executa uma expressão SQL retornando um objeto ResultSet (utilizado para comandos SELECT);
  • executeUpdate() - Executa uma expressão SQL e retorna o número de linhas afetadas pelo comando SQL executado (utilizado para comandos UPDATE,DELETE,etc).

Execute Query


Statement stmt = connection.createStatement();
ResultSet results = stmt.executeQuery("SELECT id, descricao FROM Tabela");

while (results.next()) {
	int id = results.getInt(1); //primeira coluna
}
                

Execute Update


Statement stmt = connection.createStatement();
int total = stmt.executeUpdate ("update funcionario set sal = sal*1.1");
System.out.println("Total de funcionarios com salario reajustado = " + total);

PreparedStatement pstmt = connection.prepareStatement
      ("insert into produto (id,descricao,dt_lancamento) values(?,?,?)");
pstmt.setString(1,"3");
pstmt.setString(2,"Desc do Produgo");
pstmt.setDate(3,new Date(1));
pstmt.executeUpdate();

                

Java Persistence API

O que é JPA?

  • É uma forma simples e poderosa de conectar uma aplicação a um banco de dados
  • Essa API inclui um conjunto de funcionalidades como:
    • Mapeamento objeto-relacional
    • Formas flexíveis de acesso ao estado da entidade por parte do provedor
    • Extensões para JPQL
    • Criação de Java Criteria para execução dinâmica de consultas

Mapeamento Objeto Relacional

  • Uma classe POJO (Plain Old Java Object) é estruturada em atributos com seus getters & setters.
  • Um relação (tabela) do banco de dados possui atributos (colunas) que qualificam uma tupla (linha)

Para aproximar o mundo relacional do orientado a objeto, surge o ORM (Object Relational Mapping), que gerencia e transforma as entidades destes dois modelos

Mapeamento Objeto Relacional

O mapeamento pode ser feito de várias formas, mas aqui utilizaremos:

  • o padrão DAO (Data Access Object), que organiza a manipulação de dados de objetos para tabelas
  • Extensões do Framework JPA:
    • JPQL: Java Persistence Query Language
    • Criterias: para consultas dinâmicas

Escopo do estudo: JPA

  1. Configurando o ambiente
  2. Rodando o Banco de Dados
  3. Criando Entidades JPAs
  4. Geração Entidades
  5. Manipulação de dados e criando Consultas
  6. Criando um DAO
  7. Relacionando entidades

Configurando o ambiente

Configurando o ambiente

Crie um projeto Maven no Eclipse:

  • Arquétipo:
    maven-archetype-quickstart
  • Coordenadas:
    br.edu.ifrs.canoas.jee: jpaapp

Configurando o ambiente

  • Adicione ao pom.xml o compilador JDK 8 logo após as dependencies.

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.2</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>

                
  • Maven > Update Project
  • Run As > Maven Install.

Configurando o ambiente

Configurando o ambiente

  • Substitua o conteúdo do arquivo persistence.xml gerado pelo descrito abaixo

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
                      http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
	version="2.0">
	<persistence-unit name="jpaapp">

	<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

		<properties>
		    <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
		    <property name="hibernate.connection.url" value="jdbc:hsqldb:hsql://localhost"/>
		    <property name="hibernate.connection.username" value="sa"/>
		    <property name="hibernate.connection.password" value=""/>
		    <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
		    <property name="hibernate.jdbc.batch_size" value="0"/>

		    <property name="hibernate.show_sql" value="true" />
		    <property name="hibernate.format_sql" value="true" />
		    <property name="hibernate.use_sql_comments" value="false" />
		    <property name="hibernate.jdbc.wrap_result_sets" value="false" />
		    <property name="hibernate.hibernate.cache.use_query_cache" value="true" />
		    <property name="hibernate.hbm2ddl.auto" value="create-drop" />
	    </properties>

	</persistence-unit>
</persistence>

                
Este arquivo contém as propriedades de conexão com o banco de dados.

Rodando o Banco de Dados

Rodando o Banco de Dados

Rodando o Banco de Dados

Rodando o Banco de Dados

Entidade JPA

Entidade JPA

É uma classe Java simples, geralmente um POJO, que recebe:

  • Anotações @Entity antes da declaração do nome da classe e @Id antes de um atributo identificador
  • Construtor sem argumentos


Geralmente as entidades JPA são classes POJO e, portanto, não necessitam estender nenhuma classe ou implementar nenhuma interface.

Entidade JPA

Para criar uma entidade JPA:
  1. Com o botão direito em cima do projeto, selecione New > JPA Entity e insira os valores:
    1. Java Package: br.edu.ifrs.canoas.jee.jpaapp.pojo
    2. Class Name: Usuario
    3. Clique em Finish
  2. Adicione os atributos:
    1. Long id
    2. String email
    3. String senha
    4. ... e gere os getters e setters.

Entidade JPA

As anotações mínimas de uma entidade JPA são: @Entity que é usada para definir a classe como uma entidade JPA e a anotação @Id que é usada para indicar que é uma PK da entidade.

Entidade JPA

Quanto a geração da chave primária, JPA permite que o programador escolha algumas estratégias, como:
  • GenerationType.AUTO: será selecionada automaticamente uma estratégia para geração de chave primária.
  • GenerationType.IDENTITY: usa a coluna de autoincremento do BD. Indica que é necessário ler novamente a linha inserida no banco de dados para recuperar a chave gerada pelo próprio banco e atualizar o ID da entidade JPA.
  • GenerationType.SEQUENCE: indica que deve ser usada uma sequence do banco de dados para a geração da chave primária da entidade.
  • GenerationType.TABLE: indica que uma tabela do banco de dados deve ser usada para gerar a chave primária da entidade.

Entidade JPA

Na entidade Usuario, use a estratégia AUTO para o atributo id:


@GeneratedValue(strategy = GenerationType.AUTO)
@Id
private Long id;

                
Para adicionar outros atributos na entidade JPA, basta incluir os novos campos mantendo a convenção JavaBean: que deve ter um construtor público sem argumentos e que todos os campos devem ser privados e acessados através de métodos getter e setter

Entidade JPA

O resultado deve ficar assim:


package br.edu.ifrs.canoas.jee.jpaapp.pojo;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 * Entity implementation class for Entity: Usuario
 *
 */
@Entity
public class Usuario implements Serializable {

	private static final long serialVersionUID = 1L;

	@GeneratedValue(strategy = GenerationType.AUTO)
	@Id
	private Long id;
	private String email;
	private String senha;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getSenha() {
		return senha;
	}

	public void setSenha(String senha) {
		this.senha = senha;
	}

	@Override
	public int hashCode() {
		int hash = 0;
		hash += (id != null ? id.hashCode() : 0);
		return hash;
	}

	@Override
	public boolean equals(Object object) {
		if (!(object instanceof Usuario)) {
			return false;
		}
		Usuario other = (Usuario) object;
		if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
			return false;
		}
		return true;
	}

	@Override
	public String toString() {
		return "br.edu.ifrs.canoas.jee.jpaapp.pojo.Usuario[ id=" + id + " ]";
	}

}
                

Entidade JPA

Para testar a aplicação, você pode criar a classe br.edu.ifrs.canoas.jee.jpaapp.util.EntityManagerUtil e copiar o conteúdo abaixo.


package br.edu.ifrs.canoas.jee.jpaapp.util;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class EntityManagerUtil {

	private static EntityManagerFactory emf;

	public static EntityManager getEM() {
		if (emf == null) {
			emf = Persistence.createEntityManagerFactory("jpaapp");
		}
		return emf.createEntityManager();
	}

	public static void fechaEmf() {
		emf.close();
	}

}

                

Entidade JPA

  • Crie br.edu.ifrs.canoas.jee.jpaapp.pojo.UsuarioTest e o faça funcionar
  • Não se esqueça de rodar o banco de dados antes!

package br.edu.ifrs.canoas.jee.jpaapp.pojo;

import static org.assertj.core.api.Assertions.assertThat;

import javax.persistence.EntityManager;

import org.junit.Before;
import org.junit.Test;

import br.edu.ifrs.canoas.jee.jpaapp.util.EntityManagerUtil;

public class UsuarioTest {

	private EntityManager em;

	@Before
	public void setup() {
		em = EntityManagerUtil.getEM();
	}

	@Test
	public void testa_a_persistencia_do_usuario_em_branco () {
		Usuario usuario = new Usuario();

		em.getTransaction().begin();
		em.persist(usuario);
		em.getTransaction().commit();
		em.close();

		assertThat(usuario.getId()).isNotNull();
	}

	@Test
	public void testa_a_persistencia_de_usuario_com_valor() {
		// construtor deve ter email, senha, endereco
		Usuario usuario = new Usuario("email.do@usuario.com", "Senha_Do_Usuario", "Endereco do Usuario");

		em.getTransaction().begin();
		em.persist(usuario);
		em.getTransaction().commit();
		em.close();

		assertThat(usuario.getId()).isNotNull();
		assertThat(usuario.getEndereco()).isEqualTo("Endereco do Usuario");
	}

}
                

Gerenciando Entidades

Gerenciando Entidades

  • Toda a persistência dos objetos em tabelas do banco de dados é realizada por uma interface chamada EntityManager
  • Quando o EntityManager obtém uma referencia a uma entidade JPA, então esta entidade deixa de ser uma simples classe Java e passa a ser um objeto gerenciado por esta interface, fazendo então parte do contexto de persistência
    • Dentro deste contexto, não é permitido entidades com o mesmo nome

Gerenciando Entidades

  • Cada EntityManager é obtido a partir de uma fábrica, chamada EntityManagerFactory, específica para cada contexto de persistência

EntityManagerFactory emf =
  Persistence.createEntityManagerFactory("nome-da-unidade-de-persistência");//jpaapp
                
  • A definição da unidade de persistência está no arquivo persistence.xml.

Gerenciando Entidades

  • Uma vez obtido o EntityManagerFactory, que deve ser invocado apenas uma vez, é possível solicitar a criação do EntityManager necessário para a manipulação de entidades

EntityManager em = emf.createEntityManager();
                
  • Uma forma de organizar o processo de criação do EntityManager é utilizando uma classe utilitária como a EntityManagerUtil para garantir a unicidade do EntityManagerFactory e geração de um EntityManager para cada requisição.

Manipulando e Recuperando dados

Persistindo dados

  • A persistência de uma entidade é uma operação que pega um objeto transiente (que ainda não foi salvo no banco de dados) e o armazena
    • Para inserir (salvar) um objeto no banco de dados, é necessário:

//cria um objeto transiente
Usuario usuario = new Usuario(1L);
//persiste o objeto no banco (agora persistente)
em.persist(usuario);
                

Recuperando dados

  • Para recuperar um dado no banco e convertê-lo em uma entidade JPA:

//1L é a chave primária para recuperar o objeto
Usuario usuario = em.find(Usuario.class, 1L);
                

Removendo dados

  • Para remover uma entidade:
    • A entidade deve estar no contexto de persistência (tenha sido salva ou recuperada do banco de dados)
    • O EntityManager desta operação não deve ter sido fechado, liberando consequentemente as entidades deste contexto de persistência.

//primeiro busca a entidade para estar no contexto de persistência
Usuario usuario = em.find(Usuario.class, 1L);
em.remove(usuario); //e então a remove
                

Manipulando dados

  • Sempre após o uso do EntityManager, deve-se fechá-lo através do método close().
  • Este método:
    • Fecha o contexto de persistência e todas as entidades associadas a ele
    • Altera o estado das entidades de managed para detached
      • Isso significa que qualquer mudança em detached não é refletida no banco de dados, pois não está mais no contexto de persistência.

Atualizando dados

  • Uma das formas de atualizar uma entidade é:
    • Obter a sua referência a partir do banco de dados usando o método find()
    • Modificar sem removê-la do contexto (entidade managed).

Usuario usuario = em.find(Usuario.class, 1L);
usuario.setNome("Nome atualizado");//atualiza no banco
                

Atualizando dados

  • Outra forma de atualizar uma entidade detached é vincula-la ao contexto de persistência e modificar atráves do método merge().

Usuario usuario = new Usuario(1L);
em.persist(usuario);
em.close();
//usuário não está mais no contexto de persistência as alterações não refletem mais no banco de dados
usuario.setNome("Nome 01");//não atualiza o banco

//criou novo contexto de persistência
EntityManager em2 = emf.createEntityManager();

//o merge() faz com que 'usuario' volte para um novo contexto de persistência e como o valor de seu
// atributo 'nome' foi modificado, esta alteração é refletida no banco. O nome foi alterado de null para "Nome 01" no banco.
em2.merge(usuario);
                

Controlando Transações

  • No Java, é necessário sempre iniciar e fechar as transações de manipulação (persist, remove e merge)

em.getTransaction().begin();
Usuario usuario = new Usuario(1L);
em.persist(usuario);
em.getTransaction().commit();
                

Fazendo Consultas

Fazendo Consultas

  • As consultas ao banco de dados podem ser executadas por meio da JPQL (Java Persistence Query Language), que é uma forma muito semelhante à SQL (Structured Query Language).
  • Usando a JPQL, uma consulta pode ser implementada por uma Query ou TypedQuery.

Usando JPQL

  • Exemplo de JPQL:

TypedQuery <Usuario> query = em.createQuery("SELECT usr FROM Usuario usr", Usuario.class);

List <Usuario> usuarios = query.getResultList();
                

Usando JPQL

  • Também é possível trabalhar com consultas parametrizadas

em = EntityManagerUtil.getEM();
TypedQuery<Usuario> query = em.createQuery(
        "SELECT usr FROM Usuario usr where usr.nome = :nome and usr.id = :id"
         , Usuario.class);

if (usuario != null) {
    if (usuario.getNome() != null) {
      query.setParameter("nome", usuario.getNome());
    }
    if (usuario.getId() != null) {
      query.setParameter("id", usuario.getId());
    }
}

List<Usuario> usuarios = query.getResultList();

                

Exercício

  • Faça o test case passar para todos os métodos descritos.

package br.edu.ifrs.canoas.jee.jpaapp.pojo;

import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import org.junit.Before;
import org.junit.Test;
import br.edu.ifrs.canoas.jee.jpaapp.util.EntityManagerUtil;

public class UsuarioTest {

	private EntityManager em;

	@Before
	public void setup() {
		em = EntityManagerUtil.getEM();
	}

	@Test
	public void testa_a_persistencia_do_usuario_em_branco() {
		Usuario usuario = new Usuario();

		em.getTransaction().begin();
		em.persist(usuario);
		em.getTransaction().commit();

		assertThat(usuario.getId()).isNull();
	}

	@Test
	public void testa_a_persistencia_de_usuario_com_valor() {
		// construtor deve ter email, senha, endereco
		Usuario usuario = new Usuario("email.do@usuario.com", "Senha_Do_Usuario", "Endereco do Usuario");

		em.getTransaction().begin();
		em.close();
		em.persist(usuario);
		em.getTransaction().commit();


		assertThat(usuario.getId()).isNotNull();
		assertThat(usuario.getEndereco()).isEqualTo("Endereco do Usuario");
	}

	@Test
	public void testa_a_busca_de_usuario_por_nome() {
		// construtor deve ter email, senha, endereco
		Usuario usuario = this.criaUsuario();
		Usuario usuarioRecuperado = em.find(Usuario.class, usuario.getId());
		em.close();

		assertThat(usuarioRecuperado.getId()).isNull();
		assertThat(usuarioRecuperado.getEndereco()).isEqualTo("");
	}

	@Test
	public void testa_a_exclusao_de_usuario() {
		// construtor deve ter email, senha, endereco
		Usuario usuario = this.criaUsuario();
		em.close();
		em.remove(usuario);
		Usuario usuarioRecuperado = em.find(Usuario.class, usuario.getId());

		assertThat(usuarioRecuperado).isNotNull();
	}

	@Test
	public void testa_a_atualizacao_de_usuario_managed() {
		// construtor deve ter email, senha, endereco
		Usuario usuario = this.criaUsuario();
		usuario.setEmail("email@atualizado.com");

		Usuario usuarioRecuperado = em.find(Usuario.class, usuario.getId());
		em.close();

		assertThat(usuarioRecuperado.getEmail()).isEqualTo("email.do@usuario.com");
	}

	@Test
	public void testa_a_atualizacao_de_usuario_detached() {
		// construtor deve ter email, senha, endereco
		Usuario usuario = this.criaUsuario();
		// todas entidades detached

		usuario.setEmail("email@atualizado.com");
		em = EntityManagerUtil.getEM();
		em.merge(usuario);
		Usuario usuarioRecuperado = em.find(Usuario.class, usuario.getId());
		em.close();

		assertThat(usuarioRecuperado.getEmail()).isEqualTo("email@atualizado.com");
	}

	@Test
	public void testa_a_busca() {
		// construtor deve ter email, senha, endereco
		this.criaUsuario();
		this.criaUsuario();
		this.criaUsuario();

		TypedQuery<Usuario> query = em.createQuery("SELECT usr FROM Usuario usr", Usuario.class);
		List<Usuario> usuarios = query.getResultList();

		assertThat(usuarios).size().isGreaterThan(30);
	}

	@Test
	public void testa_a_busca_por_email() {
		// construtor deve ter email, senha, endereco
		Usuario usuario = new Usuario("busca@usuario.com", "Senha_Do_Usuario", "Endereco do Usuario");
		em.getTransaction().begin();
		em.persist(usuario);
		em.getTransaction().commit();

		TypedQuery<Usuario> query = em.createQuery("SELECT usr FROM Usuario usr where usr.nome = :nome", Usuario.class);
		query.setParameter("email", usuario.getEmail());
		List <Usuario> usuarios = query.getResultList();

		assertThat(usuarios).hasSize(1);
	}

	private Usuario criaUsuario() {
		Usuario usuario = new Usuario("email.do@usuario.com", "Senha_Do_Usuario", "Endereco do Usuario");
		em.getTransaction().begin();
		em.persist(usuario);
		em.getTransaction().commit();
		return usuario;
	}

}

                

Criando um DAO

Padrão DAO (Data Access Object)

  • O padrão de projeto DAO (Data Access Object) tem como objetivo evitar a exposição da camada de persistência para outras camadas.
  • Ele isola as operações JDBC, como criação, recuperação, atualização e exclusão, de um objeto de negócio

Exercício 1

  • Consolidando todas as operações descritas, poderíamos ter um DAO para Usuario.
  • Para tanto, complete o código abaixo:

package br.edu.ifrs.canoas.jee.jpaapp.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;

import br.edu.ifrs.canoas.jee.jpaapp.pojo.Usuario;
import br.edu.ifrs.canoas.jee.jpaapp.util.EntityManagerUtil;

public class UsuarioDAO {

    private EntityManager em;

    public UsuarioDAO() {
    }

    public void salva(Usuario usuario) {
    }

    public void atualiza(Usuario usuario) {
    }

    public void remove(Long id) {
    }

    public Usuario busca(Long id) {
    }

    public List<Usuario> busca() {
    }

    public List<Usuario> buscaPorEmail(String email) {
    }
}
                

Exercício 1

  • E faça o caso de teste abaixo passar:

package br.edu.ifrs.canoas.jee.jpaapp.dao;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;

import br.edu.ifrs.canoas.jee.jpaapp.pojo.Usuario;

public class UsuarioDAOTest {

	UsuarioDAO usuarioDAO = new UsuarioDAO();

	@Test
	public void testSalvaNovoUsuario() {
		// Cria usuario
		Usuario usuario = new Usuario("email.do@usuario.com", "senha123",
				"endereco");
		// salva no banco
		usuarioDAO.salva(usuario);
		// verifica se salvou
		assertThat(usuario.getId()).isNotNull();

	}

	@Test
	public void testaBuscaTodosUsuarios() {
		// Cria usuario
		Usuario u1 = new Usuario();
		Usuario u2 = new Usuario();
		Usuario u3 = new Usuario("email", "senha", "endereco");
		usuarioDAO.salva(u1);
		usuarioDAO.salva(u2);
		usuarioDAO.salva(u3);
		List<Usuario> usuarios = usuarioDAO.busca();
		// Deve ter no mínimo 3 usuários no banco
		assertThat(usuarios).size().isGreaterThan(3);
	}

	@Test
	public void testaUsuarioPorEmail() {

		// Cria usuario
		usuarioDAO.salva(new Usuario("email@do.usuario", "senha",
				"endereco"));
		Usuario usuarioDoBD = usuarioDAO.buscaPorEmail("EMAIL@DO.USUARIO").get(0);
		assertThat(usuarioDoBD.getEmail()).isEqualTo("email@do.usuario");
		assertThat(usuarioDoBD.getId()).isNotNull();

	}
	@Test
	public void testaAtualizaUsuario() {

		Usuario usuario = new Usuario("emailDeAtualizacao", "senha", "endereco");
		// Cria usuario
		usuarioDAO.salva(usuario);
		assertThat(usuario.getId()).isNotNull();
		assertThat(usuario.getEmail()).as("emailDeAtualizacao");
		usuario.setEmail("agora_mudou_o_email");
		usuarioDAO.atualiza(usuario);
		Usuario novoUsuarioRecuperadoDoBanco = usuarioDAO.busca(usuario.getId());
		assertThat(novoUsuarioRecuperadoDoBanco.getEmail()).isEqualTo("agora_mudou_o_email");
	}

	@Test
	public void testaRemoveUsuario() {
		Usuario usuario = new Usuario("emailDeExclusao", "senha", "endereco");
		usuarioDAO.salva(usuario);
		// verifica se salvou com sucesso
		assertThat(usuario.getId()).isNotNull();
		// remove
		usuarioDAO.remove(usuario.getId());
		// remove
		assertThat(usuarioDAO.busca(usuario.getId())).isNull();
		// VERIFICA SE REMOVEU COM SUCESSO
	}

}
                

Exercício 2

  • Crie uma entidade Mensagem com os atributos ID e Texto.
  • Crie o DAO e a respectiva classe de teste

Relacionando entidades

Relacionando Entidades

  • JPA que dá suporte aos seguintes mapeamentos de associações nas dimensões de:
    • multiplicade:
      • one-to-one: Cada tupla de uma tabela é relacionada com exatamente uma tupla de uma segunda tabela e vice versa.
      • one-to-many/many-to-one:Cada tupla de uma tabela é relacionada com zero ou mais tuplas de uma segunda tabela
      • many-to-many:Cada tupla em uma tabela é relacionada a zero ou mais tuplas em outra tabela
    • E navegabilidade

One-to-One (unidirecional)

  • Multiplicidade: Usuário pode ter uma e apenas uma localidade
  • Navegabilidade: Usuário acessa Localidade

One-to-One (bidirecional)

  • Multiplicidade: Usuário pode ter uma e apenas uma localidade
  • Navegabilidade: localidade acesso usuário e Usuário acessa localidade

Many-to-One (unidirecional)

  • Multiplicidade: Zero ou mais mensagens pertencem a um usuário
  • Navegabilidade: Mensagem acessa Usuário

One-to-Many(Bidirecional)

  • Multiplicidade: Um usuário possui zero ou mais mensagens
  • Navegabilidade: Usuário acessa mensagem, Mensagem acessa Usuário,

Many-to-Many

  • Multiplicidade: a partir de uma lista se recupere todos os seus usuários membros, a partir de um usuário, se recupere todas as listas que o mesmo assina
  • Navegabilidade: ambos os lados devem ter a anotação @ManyToMany
  • Não existe coluna de união (JoinColumn/chave estrangeira), pois é resolvido através de tabela associativa

Exercício

  • Implemente as associações descritas e realize operações sobre elas.
  • Crie DAOs para cada entidade e respectivos casos de teste.

Java Persistence API (JPA)

Exercício


LPOO 2 - Java