Obrigado por visitar a devmedia.com.br!

Precisamos de você para divulgar nossos vídeos e cursos gratuitos para a comunidade.

Se você gosta da devmedia.com.br por favor dê-nos o seu clique para o Google+ e ajude outros desenvolvedores ao redor do mundo.



Obrigado por seu apoio!
Equipe DevMedia

sair sem compartilhar (x)
DevMedia - asp.net, Java, Delphi, SQL e web Design, tudo em um só lugar!
Bem vindo a DevMedia!
LOGIN:     SENHA:

Fazendo cache de objetos com Hibernate - Parte I

Este artigo vai demonstrar como fazer cache de objetos com o Hibernate, para aumentar a performance de sua aplicação.

 

Este artigo vai demonstrar como fazer cache de objetos com o Hibernate, para aumentar a performance de sua aplicação.

 

O artigo está dividido em 2 partes. A primeira explica o funcionamento do cache da Session (cache simples), e a segunda será sobre o Second Level Cache (cache avançado).

Hibernate

Para rodar o exemplo deste artigo, faça o download do Hibernate 3.1.3:

 

Þ      http://prdownloads.sourceforge.net/hibernate/hibernate-3.1.3.zip

 

Após fazer o download, coloque o arquivo “hibernate.jar” no classpath do seu projeto, assim como todos os outros jar’s encontrados na pasta “lib”.

Criando o POJO

Para testar o cache, vamos criar uma simples classe “Notícia”.

 

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

      "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

 

<hibernate-mapping>

<class

    name="model.Noticia"

    table="Noticia"

    >

      <id

        name="id"

        type="java.lang.Integer"

        column="ID"

    >

        <generator class="native" />

    </id>

      <property

        name="titulo"

        type="java.lang.String"

        column="titulo"

        length="50"

        not-null="true"

    />

</class>

</hibernate-mapping>

 

public class Noticia {

      private Integer id;

      private String titulo;

//get e set …

}

 

Criando a Tabela Notícia:

 

create table Noticia (

ID integer generated by default as identity (start with 1),

titulo varchar(50) not null,

primary key (ID))

 

E o arquivo hibernate.cfg.xml (Altere a URL e driver JDBC para o banco de dados de sua preferência):

 

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

 

<hibernate-configuration>

  <session-factory>

 

    <!-- HSQLDB -->

    <property name="hibernate.connection.driver_class">

        org.hsqldb.jdbcDriver</property>

    <property name="hibernate.connection.url">

        jdbc:hsqldb:hsql://localhost/hello</property>

    <property name="hibernate.connection.username">sa</property>

    <property name="hibernate.connection.password" />

    <property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>

 

    <property name="hibernate.show_sql">true</property>

 

    <mapping resource="model/Noticia.hbm.xml" />

 

  </session-factory>

</hibernate-configuration>

First-Level cache - Session Cache

Sempre que o Hibernate busca um objeto utilizando os métodos “load” e “get”, o resultado é armazenado no cache da Session, conhecido como first-level cache. Este cache é default no Hibernate e não pode ser desabilitado. O objeto “Session” representa uma conexão com o banco de dados, e não deve “viver” por muito tempo, desta forma é uma boa prática (recomendado) que a Session seja eliminada ao final de uma transação/requisição com o servidor. Desta forma, a conexão com o banco é fechada (ou retornada ao pool)  e o cache da Session também é apagado.

 

O Exemplo abaixo faz uma simples busca de uma notícia com o ID=1. Note que a busca é feita 2 vezes para a Notícia, mas o Hibernate vai acessar o banco de dados apenas uma vez. Entre a 1ª e a 2ª busca, foi incluído um trecho de código que faz um UPDATE com JDBC, para atualizar o título da notícia. Porém como era esperado, o Hibernate manteve a Notícia no cache da Session, e o título da 2ª busca ainda é uma informação antiga.

 

Ao rodar o exemplo, vamos supor que existe uma notícia na tabela com o ID = 1.

 

public class Teste1 {

      public static void main(String[] args) throws Exception {

            SessionFactory sessionFactory =

                         new Configuration().configure().buildSessionFactory();

            Session session = sessionFactory.openSession();

            Transaction t = session.beginTransaction();

 

            //Recupera a notícia do banco. Insere no cache da Session

            System.out.println("1 - pre session.get");

            Noticia n = (Noticia) session.get(Noticia.class, new Integer(1));

            System.out.println("1 - pos session.get");

            System.out.println(n.getTitulo());

           

            //Atualiza a tabela usando JDBC.

            Class.forName("org.hsqldb.jdbcDriver");

            Connection conn = DriverManager.getConnection

                                ("jdbc:hsqldb:hsql://localhost/hello","sa","");

            Statement stmt = conn.createStatement();

            stmt.executeUpdate("update noticia set titulo = 'novo titulo'");

 

//Tire o comentário para remover a Notícia do cache da Session

            //session.evict(n);

           

//A segunda busca vai imprimir o título antigo da notícia.

            System.out.println("2 - pre session.get");

            n = (Noticia) session.get(Noticia.class, new Integer(1));

            System.out.println("2 - pos session.get");

            System.out.println(n.getTitulo());

 

            t.commit();

            session.close();

      }

}

 

Saída:

 

1 - pre session.get

Hibernate: select noticia0_.ID as ID0_0_, noticia0_.titulo as titulo0_0_, noticia0_.texto as texto0_0_ from Noticia noticia0_ where noticia0_.ID=?

1 - pos session.get

Titulo antigo

2 - pre session.get

2 - pos session.get

Titulo antigo

 

O texto “Título antigo” apareceu duas vezes, como era esperado.

 

Note que está comentado a linha com o código: “session.evict(n);”. O método evict(object) da classe Session elimina o objeto do cache, fazendo com que o Hibernate consulte o banco de dados todas as vezes que precisar de determinada informação. Faça o teste!

Entendendo o First-Lavel cache

Sempre que uma nova Session é aberta, uma nova conexão com o servidor é realizada e um novo cache é criado. Quando a Session for fechada, o seu cache correspondente também é eliminado. O cache de uma Session não interfere em outra Session.

 

Para comprovar isto, altere o código anterior, para fechar a Session atual, e abrir uma nova antes de fazer a segunda consulta.

 

//1ª consulta…

//JDBC com update…

 

t.commit();

session.close();//fecha a 1ª session (fecha conexão e elimina o cache)

 

session = sessionFactory.openSession(); //cria uma nova session

t = session.beginTransaction();

 

//nesta session os dados serão consultados do banco de dados

//2ª consulta…

 

O resultado da execução deste código pode ser visualizado abaixo:

 

1 - pre session.get

Hibernate: select noticia0_.ID as ID0_0_, noticia0_.titulo as titulo0_0_, noticia0_.texto as texto0_0_ from Noticia noticia0_ where noticia0_.ID=?

1 - pos session.get

Titulo Antigo

2 - pre session.get

Hibernate: select noticia0_.ID as ID0_0_, noticia0_.titulo as titulo0_0_, noticia0_.texto as texto0_0_ from Noticia noticia0_ where noticia0_.ID=?

2 - pos session.get

Novo titulo

 

Note que o Hibernate fez 2 consultas no banco. E que o título da notícia foi atualizano na segunda busca.

 

Lembre-se de que outra maneira de eliminar um objeto da cache (sem fechar a Session) é chamando o método “session.evict(obj)”.

Conclusão

Neste artigo foi explicado como funciona o first level cache do Hibernate, o qual armazena os objetos para a Session corrente.

 

Este cache é muito simples para ser utilizado em aplicações Web, onde geralmente a cada requisição ao servidor, uma nova Session é criada. Então fica a pergunta, como utilizar cache de objetos mesmo Sessions (conexões) diferentes?

 

Para isto existe o Second-Level cache, que é uma estratégia de cache um pouco mais agressiva e eficiente, onde alguns frameworks como o EHCache e OSCache são utilizados. Este cache será explicado na 2ª parte do artigo.





    0 COMENTÁRIO

[Fechar]

Este post é fechado - você precisa ter acesso ao post para incluir um comentário.


Nenhum comentário foi postado - seja o primeiro a comentar!



Autor
Ricardo Rodrigues Lecheta

Ricardo Rodrigues Lecheta (ricardolecheta@terra.com.br), é autor do livro “Google Android” - Aprenda a criar aplicações para dispositivos móveis utilizando o Android SDK e possui as certificações SCJP, SCWCD, SCBCD, SCMAD, SCEA.


Space do autor
Estatísticas
Favorito:
Comentários:
Feedback:
Utilidade:
1   1
[Fechar]

Você precisa estar logado para dar um feedback.

Clique aqui para efetuar o login
[Fechar]
Este post está disponível para assinantes da Java Magazine ou para quem possui Créditos DevMedia.

  Conheça os planos de créditos DevMedia e visualize esse post agora mesmo!

Plano conveniência – Neste plano este post custa R$ 0,00 (Compre agora)
Esse plano permite que você compre somente um post, pagando por ele seu preço sem desconto.

Plano ocasional: Aqui este post custa: R$ -1,00 (assinante) ou R$ -1,00 (não-assinante)
Este plano é ideal para quem tem interesse em mais de um post. Você compra um mínimo de R$ 50,00 em créditos e ganha, em média, 50% de desconto no preço do post. Compre Créditos agora!

Assinatura de Créditos (Plano econômico) – Aqui este post custa R$ -1,00
Este plano é ideal para quem tem interesse em muitos posts. Com esse plano você compra R$ 180,00 em créditos e ganha, em média, 80% de desconto no preço do post. Assine este plano agora!

> Saiba mais sobre o Sistema de Créditos DevMedia
web-03
DevMedia  |  Anuncie  |  Fale conosco
Hospedagem web por Porta 80 Web Hosting
2012 - Todos os Direitos Reservados a web-03