sábado, 3 de maio de 2008

Tagged under: ,

Desenvolvendo uma aplicação web de forma fácil e prática – 6ª parte - final

Você, leitor, que acompanhou nossa “receita de bolo” para fazer uma aplicação web, deve ter percebido como é fácil e prático assim fazê-lo usando o JSF, o Hibernate e a IDE Netbeans 6. Neste post final, comentarei o que fizemos e deixamos de fazer aqui para que seu conhecimento não fique limitado apenas ao que mostrei no tutorial. É sempre importante aprendermos com exemplos e depois buscarmos o conhecimento do motivo de ter sido feito daquele jeito, e não de outro.

No primeiro post, vimos as linhas gerais da arquitetura da aplicação e o escopo de nosso exemplo. Nossa arquitetura divide-se em dois componentes principais: a camada de aplicação e a camada de interface web. Numa comparação com o tradicional modelo MVC (Model-View-Controller), nossa camada de aplicação abriga as camadas Model e Controller; a camada web abriga a camada View e a Controller.

Você pode se perguntar agora por que a camada Controller está nas duas camadas de nosso exemplo, e eu explico. No modelo MVC, Controller é a parte onde fica os objetos que desviam o fluxo de execução de uma tarefa para o local adequado. O managed bean Page que interage com o JSP faz isso, assim como o Facade do lado da camada Aplicação. Entendeu, agora? Para aprender mais sobre o modelo MVC, sugiro este artigo do site Macoratti.net e este da empresa Fragmental.

Com nossa arquitetura, será bastante fácil você, no futuro, criar uma interface desktop ou para dispositivos móveis, já que a camada de Aplicação não precisará ser refeita. Somente será necessário criar a camada Desktop, ou uma camada Celular.

No segundo post, nós criamos o banco de dados (relacional), configuramos as bibliotecas necessárias para nosso projeto, e extraímos as classes-entidade a partir do banco de dados, fazendo uma espécie de “engenharia reversa”. Também configuramos a unidade de persistência para que a aplicação possa estabelecer as conexões com o banco de dados e usar o Hibernate como provedor de persistência.

Do jeito que deixamos o arquivo persistence.xml, o Hibernate está conectando-se ao banco de dados da maneira mais “burra” que existe. Foi deixado assim propositadamente para não dificultar o aprendizado no tutorial. Isso só deve ser feito em tempo de desenvolvimento. Nossa unidade de persistência não está usando os recursos de cache e nem pool de conexões do provedor Hibernate. Para melhorarmos a performance, necessária para um ambiente de produção, é necessária uma intervenção manual no arquivo XML.

O Hibernate tem vários tipos de cache. O mais usado é o EHCache e, para configurá-lo, basta modificar a seguinte linha do arquivo persistence.xml:
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"></property>
para
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"></property>

O Hibernate também tem várias opções de pool de conexões. A maneira mais simples de usarmos um pool é fazermos a configuração padrão da especificação JPA, ou seja, usarmos o pool do próprio servidor web (no caso, o Tomcat). Primeiro, abra o arquivo context.xml, que fica dentro do projeto JavaBahiaWeb e mude-o para ficar assim:

<context path="/javabahia">
<resource name="jdbc/JavaBahiaDB" auth="Container" type="javax.sql.DataSource" maxactive="10" maxidle="1" maxwait="10000" username="root" password="" driverclassname="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/javabahia">
</resource></context>


Depois, volte no arquivo persistence.xml, e insira a seguinte linha, logo abaixo da tag provider:
<non-jta-data-source>java:comp:env/jdbc/JavaBahiaDB</non-jta-data-source>

Na parte onde configuramos as propriedades (properties), substitua as linhas que possuem o nome da propriedade iniciando com 'hibernate.connection' pela linha abaixo(é importante substituir, e não acrescentar, com riscos de dar erro depois):
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"></property>

Agora, sua conexão com o banco de dados já poderá ser feita da melhor forma.

No terceiro post, criamos as classes de persistência dos objetos-entidade – chamados DAO – e a classe de acesso à nossa camada de Aplicação – a classe façade.

O façade é um padrão de projeto (design pattern) utilizado para simplificar o uso de um conjunto maior de código, encapsulando-o e isolando-o. O nosso JavaBahiaFacade.java é o único ponto de chamada de operações para a camada de Aplicação. A camada de Web somente usa essa classe para realizar as tarefas que foram requisitadas pelos usuários.

O DAO (Data Access Object) é um padrão JEE para estabelecer um “tradutor” entre o mundo orientado a objeto e o mundo relacional (da maioria dos bancos de dados). Isolando essa transformação em uma classe responsável por isto, ganhamos a flexibilidade de podermos mudar, a qualquer momento, a forma como persistimos os nossos objetos. Alguns autores chamam esse padrão de Data Mapper.

No quarto post, começamos a construir a camada Web, responsável por fazer a interface com o usuário da aplicação. Fizemos uso da API Visual Web do Netbeans (conhecido como projeto WoodStock); essa API traz componentes JSF que facilitam a vida do desenvolvedor web. Nesse post, construímos a tela de acesso à aplicação e vimos como usar os managed beans para controlar o fluxo do sistema.

No quinto post, fizemos a tela de manutenção do cadastro de uma das entidades de nosso contexto, usando o conceito CRUD. O CRUD (Create-Retrieve-Update-Delete) é um conceito que traduz as quatro operações básicas de um armazenamento de informação. Na maioria das entidades de um sistema, temos as operações de criação (create), recuperação (retrieve), atualização (update), e exclusão (delete).

Vimos nesse post, também, o uso do objeto provedor de dados (data provider). Esse objeto é importante para mantermos a ilusão de que a tabela acessa diretamente o banco de dados, sem que a divisão das camadas de nosso sistema seja quebrada. O componente Data Table, do projeto WoodStock, já traz prontas as funcionalidades de paginação e ordenação e, para isso, precisa desse objeto provedor de dados.

Algumas coisas foram esquecidas nesse exemplo, como a validação, por exemplo, para que não fosse prejudicado o entendimento do que foi abordado. Fica minha promessa de abordar esse tópico futuramente.

Eu espero que você tenha gostado deste tutorial e possa aumentar os seus conhecimentos buscando novas fontes de referência para os conceitos aqui apresentados. Estou disponibilizando o código final completo dos projetos JavaBahiaApp e JavaBahiaWeb. Originalmente estava usando o serviço 4Shared mas mudei após os arquivos terem sidos apagados.

Tenha um bom estudo e, desde já, agradeço pela sua atenção.

8 comentários:

Anônimo disse...

Cara execelente post!! Me ajudou muito em aprender a mexer no Netbeans e ver como ele facilita a vida do programador!! Mas é bom salientar para os iniciantes que precisamos aprender o que é JPA como fazer as anotações no braço!! para podermos automatizar o processo!! abraços!!! Continuem assim!! =D

Denilson Barrios disse...

Legal, vc teria um exemplo + usando o toplink ao inves de hibernete, estou tentando com:
Netbeans 6.1 + glassfish + toplink + postgres?

Obrigado!

Unknown disse...

Cara, muito bom!!!

Congrats!

Alexandre M. Lima disse...

Ramon,
Obrigado pelos elogios! Você está certo, fazer somente o que a IDE nos facilita é deixar de aprender uma tecnologia e ficar burro para sempre. Devemos conhecer a fundo para poder resolver com mais simplicidade as situações do dia a dia.

Denilson,
Eu não tenho nenhum exemplo com TopLink. Quem sabe outro post neste blog.

Fernando,
Obrigado!

Anônimo disse...

Alexandre, parabens poucos tutoriais na internet são tão bem explicados como o seu foi... fico feliz de ver que pessoas como vc não medem esforços para ajudar os principiantes e tirar umas duvidas dos mais veteranos, sua didatica foi excepcional. eu gostaria de perguntar a vc, peguei seu codigo para estudar, porem o link na tabela não seta os valores para os textfields, eu ate mexi muito no codigo para ver se resolvia, mas não consegui, por acaso vc sabe dizer o que eh.
ps.: eu utilizei o codigo do link 4shared.com.

grato abraço e parabens de novo.

Rômulo Martins disse...

Alexandre,

Excelente post!!! Obrigado por compartilhar seu conhecimento.

No meu deu um probleminha... quando eu tento me logar...dá erro.. e a tela não aparece nenhuma mensagem...

eu consigo acessar através do link direto as páginas PageEmpresas.jsp ou PageContratos.jsp... só que na hora de inserir dá este erro:

Mensagens do sistema
[PersistenceUnit: JavaBahiaAppPU] Unable to build EntityManagerFactory

Então.. eu inseri uma empresa direto no banco.. e acessei novamente a PageEmpresas.jsp... e a página não lista nenhuma empresa..

Eu já testei a conexão por uma página separada em JSP no projeto... e ele retorna normal os dados.. então.. problema de driver do mysql não é...

Eu acho que é alguma configuração no persistence.xml ou em algum outro ponto de configuração do hibernate.

Você pode me ajudar?

Desde já, obrigado pela atenção.

Alexandre M. Lima disse...

Rômulo,

Confira se no seu persistence.xml a configuração do atributo transaction-type está setada para RESOURCE_LOCAL. Pode ser isso!

Rubem Rocha disse...

O tutorial é muito bom, mas gostaria de fazer algumas observações:

1) Tentei construir o menu de acordo com o que foi exposto no tutorial, mas acontece um problema. Montei o menu principal com três opções. Ao clicar em qualquer uma delas, na primeira vez que chamo o menu principal, sou direcionado à página da respectiva opção. No entanto, caso este mesmo menu seja mostrado na página direcionada, e eu tente ir à outra opção clicada no menu dessa mesma página, sempre serei direcionada à página que fui direcionado na primeira vez. Exemplo: Tenho três opções (Produtos, Funcionários e Fornecedores) criadas em um page fragment (Cabecalho.jspf), e este cabeçalho é usado tanto pela página do menu principal (MenuPrincipal.jsp) como pelas páginas de cadastro (CadastroProdutos.jsp, CadastroFuncionario.jsp e CadastroFornecedor.jsp). Quando chamo pela primeira vez MenuPrincipal.jsp, e seleciono uma das opções mencionadas e sou direcionado à página respectiva. Mas quando tento me direcionar para outra página, a partir do Cabecalho incluído na página onde estou navegando, sempre sou direcionado à página que selecionei quando da primeira chamada do MenuPrincipal.jsp.

2) O objeto que configuro no RequestBean para ter as informações do registro cadastro perde dados das propriedades no momento que tente criar um novo registro ou alterar um registro existente. Alguma recomendação para que o objeto da camada de modelo não passe por este problema?

Sds.,

Rubem Rocha
Manaus, AM