Você está na página 1de 43

JPA - Hibernate

Introdução
Sergio Bonato – ARQDESISMULTI – USJT - 2019
Persistência de Dados

• serialização
• tabelas • arquivos
• colunas
• registros
• bancos de dados relacionais
• chaves • bancos de dados OO
• bancos de dados NoSQL
Persistência de Dados Java

Programação OO SGBD Relacional

JDBC
Persistência de Dados JDBC

Programação OO SGBD Relacional


public void excluir(Local local) throws IOException {
String sqlDelete = "delete from local where idlocal=?";
try (PreparedStatement pst = conn.prepareStatement(sqlDelete);) {
pst.setInt(1, local.getId());
pst.execute();
} catch (SQLException e) { DESVANTAGENS
e.printStackTrace(); • alto acoplamento com o banco
throw new IOException(e); • necessário grande conhecimento
} do esquema relacional
} VANTAGENS • necessidade de escrita de grande
• o programador pode otimizar os quantidade de código
comandos SQL para ter maior • gerencimento de transação manual
performance em queries pesadas e complexo
Persistência de Dados JDBC

Programação OO SGBD Relacional


public void excluir(Local local) throws IOException {
String sqlDelete = "delete from local where idlocal=?";
try (PreparedStatement pst = conn.prepareStatement(sqlDelete);) {
pst.setInt(1, local.getId());
pst.execute();
} catch (SQLException e) { DESVANTAGENS
e.printStackTrace(); • alto acoplamento com o banco
throw new IOException(e); • necessário grande conhecimento
} do esquema relacional
} VANTAGENS • necessidade de escrita de grande
• o programador pode otimizar os quantidade de código
comandos SQL para ter maior • gerencimento de transação manual
performance em queries pesadas e complexo
Persistência de Dados Java – Subindo o nível

Programação OO SGBD Relacional


JDBC

DESVANTAGENS VANTAGENS
• o programador tem que voltar para • baixo acoplamento com o banco
o JDBC para otimizar queries • desnecessário grande conhecimento
pesadas, pois os frameworks do esquema relacional
podem ter baixa performance • pouca quantidade de código
nestes casos • gerencimento de transação facilitado
JPA – Java Persistence API
JPA
Como usar JPA
Como usar JPA (1) se o Maven estiver
funcionando
Como usar JPA (1) arrastando bibliotecas
manualmente

Baixe e arraste para o


WEB-INF/lib
Mapeando a entidade de persistência (2)
@Entity
@Table(name="Uf")
public class Estado implements
Serializable{
private static final long
serialVersionUID = 1L;
@Id
@Column(name="idUf")
@Size(max=2)
private String id;
@NotNull
@Column(name="nmUf")
@Size(max=128)
private String nome;
Anotações JPA
• @Entity: necessário para toda classe do model que for persistida no
banco.
• @Table: mapeia a classe com o nome correspondente da tabela; se
omitida o Hibernate usa o nome da classe.
• @Column: mapeia o atributo para a respectiva coluna. Se omitido o
Hibernate irá inferir o nome e o tipo baseado no tipo do atributo.
• @Id e @GeneratedValue: id diz que o atributo é a PK da tabela;
GeneratedValue diz que será autoincrement.
Anotações JPA
• @Temporal: usado com o java.util.Date para mapear para o tipo data
desejado no banco.
• @OneToOne and @JoinColumn: usado para especificar um
relacionamento um para um entre tabelas e a(s) coluna(s) de junção.
• @OneToMany, @ManyToOne, @ManyToMany: indicam
relacionamentos um para muitos, muitos para um e muitos para
muitos; sempre usado em conjunção com a @JoinColumn.
Configurando a unidade de persistência (3)
Exemplo
<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="pokemapa">
<!-- provedor/implementacao do JPA -->
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!-- entidade mapeada -->
<class>br.usjt.arqdes16.mapeamento.model.Cidade</class>
<class>br.usjt.arqdes16.mapeamento.model.Local</class>
<class>br.usjt.arqdes16.mapeamento.model.Tipo</class>
<class>br.usjt.arqdes16.mapeamento.model.Usuario</class>
<properties>
Exemplo (continuação)
<!-- dados da conexao -->
<property name="javax.persistence.jdbc.driver"
value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://localhost/pokemapa_jpa?createDatabaseIfNotExist=true&amp;useUnic
ode=yes&amp;characterEncoding=UTF-8" />
<property name="javax.persistence.jdbc.user" value="alunos" />
<property name="javax.persistence.jdbc.password" value="alunos"
/>
<!-- propriedades do hibernate -->
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<!-- atualiza o banco, gera as tabelas se for preciso -->
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
Como usar o JPA (4)

equivalências no CRUD

Retrieve
Create
para de gerenciar a persistência do obj.
Update
Delete
Como usar o JPA (4)
Como usar o JPA (4) (1)
public class TesteInclusao {
public static void main(String[] args) {
EntityManagerFactory factory = Persistence
.createEntityManagerFactory("pokemapa");
EntityManager manager = factory.createEntityManager();
CidadeDAO cidadeDAO = new CidadeDAO(manager);
LocalDAO localDAO = new LocalDAO(manager);
TipoDAO tipoDAO = new TipoDAO(manager);

Tipo tipo = tipoDAO.selecionar(5);


Cidade cidadeRio = cidadeDAO.selecionar(2);
Local localBSB = new Local();
localBSB.setNome("Sir Fer MacRugem");
localBSB.setLatitude(-15.790476);
localBSB.setLongitude(-47.904464);
localBSB.setTipo(tipoErrado);
localBSB.setCidade(cidadeRio);
Como usar o JPA (4) (2)
manager.getTransaction().begin();
localDAO.criar(localRJ);
manager.getTransaction().commit();
List<Local> lista = localDAO.selecionarTodas();
for(Local local:lista){
System.out.println(local);
}
manager.close();
factory.close();
}
}
Como usar o JPA (4) (3)
public class LocalDAO {
EntityManager manager;

public LocalDAO(EntityManager manager){


this.manager = manager;
}

public void criar(Local local){


manager.persist(local);
}

public void atualizar(Local local){


manager.merge(local);
}

public void remover(Local local){


manager.remove(local);
}
Como usar o JPA (4) (4)
public Local selecionar(int id){
return manager.find(Local.class, id);
}

@SuppressWarnings("unchecked")
public List<Local> selecionarTodas(){
return manager.createQuery("select l from Local l").getResultList();
}
}
Relacionamentos
Relacionamentos
Relacionamentos
Relacionamentos
Relacionamentos
CascadeType (1)
NONE=Não faz nada com o objeto, portanto é default e não é declarável na enum;
MERGE= Faz update nos filhos quando faz update no pai, aí está seu problema, se vc
ainda não persistiu esse objeto não pode dar um update nele.
PERSIST = Salva o filho quando salva o pai, sendo assim, você pode dar um save ou
persist no objeto, mas quando for dar update vai dar erro.
REFRESH = Salva o pai e mantem o filho sem alterar.
REMOVE = Remove o filho qdo remove o pai ou vice-versa;

Fonte: http://respostas.guj.com.br/1081-cascadecascadetypexx---nao-quero-que-a-jpa-cascatei-a-entidade-filha
CascadeType (2)
ALL = Esse é o cascade do fim do mundo, você vai salva, fazer update, remover, o q
quiser com seu objeto, é altamente não recomendável utilizá-lo.

Cuidado com essas propriedades se fizer mapeamento com mapped by, sempre
coloque, se for extremamente necessário, o @Cascade no objeto pai.
Você pode combinar vários cascades para cada tipo de situação.

Fonte: http://respostas.guj.com.br/1081-cascadecascadetypexx---nao-quero-que-a-jpa-cascatei-a-entidade-filha
Integração JPA Spring
Inicializando o Entity Manager sem a Ajuda do
Spring
@RequestMapping("teste")
public void Teste(Local local, Model model) {
EntityManagerFactory factory = Persistence
.createEntityManagerFactory("pokemapa");
EntityManager manager = factory.createEntityManager();
LocalDAO localDAO = new LocalDAO(manager);
manager.getTransaction().begin();
localDAO.criar(local);
manager.getTransaction().commit();
List<Local> lista = localDAO.selecionarTodas();
model.setAttribute("lista", lista);
manager.close();
factory.close();

}
Configurando o JPA no Spring
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="mysqlDataSource" />
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
</bean>

esta configuração é feita no spring-context.xml


Detalhe da configuração
• O bean define o Hibernate como implementação do JPA e e recebe o
datasource que definimos na última aula de Spring.
• Este datasource já contém todos os dados de conexão JDBC
• string de conexão
• usuário
• senha
• Deste modo, podemos simplificar o arquivo persistence.xml
removendo estas informações.
Exemplo persistence.xml
<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="pokemapa">
<!-- provedor/implementacao do JPA -->
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<!-- entidade mapeada -->
<class>br.usjt.arqdes16.mapeamento.model.Cidade</class>
<class>br.usjt.arqdes16.mapeamento.model.Local</class>
<class>br.usjt.arqdes16.mapeamento.model.Tipo</class>
<class>br.usjt.arqdes16.mapeamento.model.Usuario</class>
<class>br.usjt.arqdes16.mapeamento.model.Estado</class>
<properties>
Exemplo persistence.xml (continuação)
<!-- dados da conexao -->

<!-- propriedades do hibernate -->


<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<!-- atualiza o banco, gera as tabelas se for preciso -->
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
Exemplo spring-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="br.usjt.arqdes16.mapeamento" />
<mvc:annotation-driven />
<mvc:default-servlet-handler />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="mysqlDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver"></property>
<property name="url"

value="jdbc:mysql://localhost/pokemapa_jpa?createDatabaseIfNotExist=true&am
p;useUnicode=yes&amp;characterEncoding=UTF-8"></property>
<property name="username" value="alunos"></property>
<property name="password" value="alunos"></property>
</bean>
<bean id="entityManagerFactory"

class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="mysqlDataSource" />
<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
</bean>
<mvc:interceptors>
<bean
class="br.usjt.arqdes16.mapeamento.interceptor.AutorizadorInterceptor" />
</mvc:interceptors>
</beans>
Injetando o Entity Manager

@RequestMapping("teste")
public void Teste(Local local, Model model) {
@Autowired
LocalDAO localDAO;

localDAO.criar(local);

List<Local> lista = localDAO.selecionarTodas();


model.setAttribute("lista", lista);

}
Injetando o EntityManager
@Repository
public class LocalDAO {
@PersistenceContext
EntityManager manager;

//sem construtor

public void criar(Local local){


manager.persist(local);
}

public void atualizar(Local local){


manager.merge(local);
}

public void remover(Local local){


manager.remove(local);
}
Injetando o EntityManager
public Local selecionar(int id){
return manager.find(Local.class, id);
}

@SuppressWarnings("unchecked")
public List<Local> selecionarTodas(){
return manager.createQuery("select l from Local l").getResultList();
}
}
Gerenciando a Transação
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<tx:annotation-driven/>

Configurar no spring-context o bean que irá gerenciar a transação e


que iremos usar anotações.
Gerenciando a transação via injeção
@Transactional
@RequestMapping("teste")
public void Teste(Local local, Model model) {
@Autowired
LocalDAO localDAO;

localDAO.criar(local);

List<Local> lista = localDAO.selecionarTodas();


model.setAttribute("lista", lista);