netbeans 6 - livro

203

Upload: saulo-cardoso

Post on 28-Dec-2015

196 views

Category:

Documents


86 download

TRANSCRIPT

Page 1: Netbeans 6 - livro
Page 2: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

22

Conteúdo 

TRABALHANDO COM TOMCAT 5.5 .......................................................................................... 9 

Adicionando na IDE o Tomcat 5.5 ............................................................................................... 9 Acessando o administrador na IDE ........................................................................................ 10 Configurando Pool de Conexões no Tomcat 5.5 pelo Admin ............................................... 14 Utilizando JNDI no arquivo persistence.xml ......................................................................... 15 Listagem 1. Alteração do arquivo persistence.xml ............................................................... 15 Listagem 2. A classe JPAToplinkSessionCustomizationUtil ............................................... 16 

APLICAÇÕES WEB COM ACESSO A DADOS SEM PADRÃO ............................................. 17 

Desenvolvendo via JDBC sem padrões ...................................................................................... 17 Criando o projeto ..................................................................................................................... 17 Conectando sua página JSP ao banco de dados .................................................................... 20 Listagem 1. Alterações na página index.jsp ........................................................................... 20 Listagem 2. Alterações na página formInserindoDados.jsp ................................................ 22 Listagem 3. Alterações na página inserindoDados.jsp ......................................................... 23 Entendendo os principais Statements .................................................................................... 25 Explorando a interface PreparedStatement .......................................................................... 25 A biblioteca de tags SQL do JSTL ......................................................................................... 25 Listagem 4. Alterações na página inserindoDados.jsp ......................................................... 27 

STRUTS FRAMEWORK ............................................................................................................... 29 

A origem do Struts Framework .................................................................................................. 29 Seu primeiro projeto com Struts ............................................................................................ 29 As camadas de Struts ............................................................................................................... 31 Listagem 1. Alterações na classe NomeForm ........................................................................ 33 Listagem 2. Alterações na classe ControleAction ................................................................. 37 Listagem 3. Alterações na classe MeuBeanModelo............................................................... 40 Listagem 4. Alterações na classe Constante ........................................................................... 41 Listagem 5. Alterações na página welcomeStruts ................................................................. 41 Listagem 6. Alterações na página sucesso.jsp........................................................................ 42 As tags do Struts ....................................................................................................................... 43 Utilizando Struts para acessar banco de dados ..................................................................... 48 Listagem 7. O JavaBean Autor ............................................................................................... 48 Listagem 8. A classe ConnectionFactory ............................................................................... 49 Listagem 9. A interface DAO .................................................................................................. 50 Listagem 10. A classe implementada AutorDAOImp .......................................................... 50 Listagem 11. A classe AutoresActionForm ............................................................................ 54 

Page 3: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

33

Listagem 12. A classe AutoresAction ..................................................................................... 55 Listagem 13. O resultado final configurado em struts-config.xml ...................................... 56 Listagem 14. A página welcomeStruts.jsp ............................................................................. 57 Listagem 15. A página index.jsp ............................................................................................. 58 Listagem 16. A classe EditarAutoresForm ............................................................................ 58 Listagem 17. A classe EditarAutoresAction .......................................................................... 59 Listagem 18. Alterações no arquivo struts-config.xml ......................................................... 63 Listagem 19. Alterações no arquivo struts-config.xml ......................................................... 64 Listagem 20. Alterações no arquivo struts-config.xml ......................................................... 65 Listagem 21. A página welcomeStruts.jsp ............................................................................. 66 

DESENVOLVENDO RELATÓRIOS COM NETBEANS IDE .................................................. 68 

O JasperReports ........................................................................................................................... 68 O iReport para o NetBeans ......................................................................................................... 68 

Desenvolvendo relatórios com NetBeans ............................................................................... 68 Listagem 1 – Trecho do Servlet Relatorio contendo a chamada ao arquivo JasperReports .................................................................................................................................................... 86 Listagem 2 – Alteração do arquivo index.jsp ........................................................................ 88 Listagem 3 – Alteração da query usada no relatório ............................................................ 90 Listagem 4 – O Servlet Relatorio ............................................................................................ 91 Listagem 5 – Chamando o Servlet por mostrarAutoresCads.jsp ........................................ 92 

ESTUDO DE CASO COMPLETO COM VISUAL WEB JSF ................................................... 94 

Adicionando novas características ao administrador ............................................................... 94 As entidades e seus relacionamentos ...................................................................................... 94 Listagem 1. Script para criação das tabelas do projeto....................................................... 95 Adicionando novas páginas do administrador ...................................................................... 96 Listagem 2. O bean Editora .................................................................................................... 97 Listagem 3. O código do link Excluir do componente Table da página .............................. 98 Listagem 4. O código do link Atualizar do componente Table da página .......................... 98 Listagem 5. O código do botão Salvar do formulário da página ......................................... 99 Listagem 6. O código do método Callback prerender() da página ...................................... 99 A página de criar publicações ............................................................................................... 100 Listagem 7. O código do botão btPublicar do formulário da página ................................ 102 Listagem 8. Alterações do código da página ........................................................................ 103 Listagem 9. Alteração em faces-config.xml para a página Publicar ................................. 107 A página de publicações ........................................................................................................ 108 Vinculando o livro a seus autores ......................................................................................... 109 Listagem 10. Alteração na classe RequestBean1 ................................................................. 109 

Page 4: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

44

Listagem 11. Código do link Adicionar ................................................................................ 110 Listagem 12. Código do botão Adicionar ao Livro ............................................................. 112 A página de autores publicados ............................................................................................ 113 Listagem 13. Navegação da página LivroAutor para AutoresPublicados ........................ 114 Alterando o menu ................................................................................................................... 115 Criando o relacionamento entre as páginas ........................................................................ 115 Listagem 13. Arquivo faces-config.xml ................................................................................ 115 

ESTUDO DE CASO COMPLETO COM VISUAL WEB JSF, SPRING E HIBERNATE UTILIZANDO JPA ....................................................................................................................... 121 

As características da aplicação ................................................................................................. 121 O Projeto ................................................................................................................................. 121 As entidades e seus relacionamentos .................................................................................... 121 As entidades POJO ................................................................................................................ 122 Listagem 1. O código da entidade Usuario .......................................................................... 124 Listagem 2. O código da entidade Livro .............................................................................. 125 Listagem 3. O código da entidade Autor.............................................................................. 125 Listagem 4. O código da entidade Editora ........................................................................... 126 Listagem 5. O código da entidade Publicacao ..................................................................... 126 Utilizando o DAO genérico para criar outros ..................................................................... 128 Listagem 6. A interface BaseDao alterada ........................................................................... 128 Listagem 7. A classe BaseDaoImp alterada ......................................................................... 128 Listagem 8. A interface EditoraDao ..................................................................................... 128 Listagem 9. A classe EditoraDaoImp ................................................................................... 128 Listagem 10. A interface LivroDao ...................................................................................... 129 Listagem 11. A classe LivroDaoImp ..................................................................................... 129 Listagem 12. A interface PublicacaoDao ............................................................................. 129 Listagem 13. A classe PublicacaoDaoImp............................................................................ 129 Listagem 14. A interface UsuarioDao .................................................................................. 129 Listagem 15. A classe UsuarioDaoImp ................................................................................. 129 Listagem 16. A classe AutorDao ........................................................................................... 129 Listagem 17. A classe AutorDaoImp .................................................................................... 130 Configurando o Spring .......................................................................................................... 130 Listagem 18. Configuração do arquivo applicationContext.xml. ...................................... 131 Listagem 19. Configurando o Spring Framework em web.xml. ........................................ 132 Criando um teste unitário ..................................................................................................... 132 Listagem 20. Teste unitário usando o Spring Framework ................................................. 133 Controlando o acesso ............................................................................................................. 134 

Page 5: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

55

Listagem 21. Métodos adicionais da classe AutorController ............................................ 135 Listagem 22. O código da classe UsuarioController .......................................................... 135 Listagem 23. O código da classe EditoraController ............................................................ 136 Listagem 24. O código da classe LivroController ............................................................... 136 Listagem 25. O código da classe PublicacaoController ...................................................... 137 Integrando o Visual Web JSF ao Spring ............................................................................. 138 Listagem 26. Alterações no arquivo faces-config.xml ......................................................... 138 Acessando o Facade pelo Visual Web JSF ........................................................................... 139 Listagem 27. Alterações na classe SessionBean1 ................................................................. 139 Os arquivos persistence.xml e log4j.properties ................................................................... 140 As páginas da aplicação ......................................................................................................... 140 Montando sua aplicação para utilizar Spring e Hibernate com JPA................................ 140 A criação do cadastro de livros ............................................................................................. 142 Listagem 28. Criação do método getLivroController() ...................................................... 143 Listagem 29. Alterações no método prerender() ................................................................. 143 Listagem 30. Alterações no método do link Excluir ........................................................... 144 Listagem 31. Alterações no método do link Editar ............................................................. 144 Listagem 32. Alterações no método do botão Salvar .......................................................... 144 As demais páginas administrativas de cadastro simples .................................................... 146 Acessando a área administrativa .......................................................................................... 147 Listagem 33. Criação do método getUsuarioController() .................................................. 148 Listagem 34. Alterações no método prerender() ................................................................. 148 Listagem 35. Alterações no método do botão Logar ........................................................... 149 A página de publicação .......................................................................................................... 150 Listagem 36. Alterações no método init() da classe SessionBean1 .................................... 150 Listagem 37. O código do botão btPublicar do formulário da página .............................. 153 Listagem 38. Alterações do código da página ...................................................................... 153 Listagem 39. Alteração em faces-config.xml para a página Publicar ............................... 155 A página de publicações ........................................................................................................ 155 Listagem 40. O bean PublicacoesBean ................................................................................. 156 Listagem 41. Alterações na classe SessionBean1 ................................................................. 157 Listagem 42. Alterações do método prerender() ................................................................. 158 Listagem 43. Alterações em Publicacoes.java ..................................................................... 159 Adicionando autores a livros ................................................................................................. 160 Listagem 44. Alteração na classe SessionBean1 .................................................................. 161 Listagem 45. Alterações no método prerender() ................................................................. 161 Listagem 46. Declaração do atributo autorOptions ............................................................ 161 

Page 6: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

66

Listagem 47. Chamando a classe AutorController ............................................................. 161 Listagem 48. Código do link Adicionar ............................................................................... 163 Listagem 49. Código do botão Adicionar ao Livro ............................................................. 164 Listagem 50. Código de getLivroController() .................................................................... 164 A página de autores publicados ............................................................................................ 165 Listagem 51. Código de AutoresLivroBean ......................................................................... 166 Listagem 52. Trecho do código de SessionBean1 ................................................................ 167 Listagem 53. Alterações do método prerender() ................................................................. 168 Pesquisando livros na página principal ............................................................................... 169 Listagem 54. Alterações na classe SessionBean1 ................................................................. 169 Listagem 55. Código no botão Buscar de topo.jspf ............................................................. 169 Listagem 56 – Chamada de LivroController na classe Pesquisado .................................. 170 Listagem 57 – Código do método prerender() na classe Pesquisado ................................. 170 Listagem 58 – Criação do array livros na classe Pesquisado ............................................ 170 Listagem 59 – Criação do array livros na classe Pesquisado ............................................ 171 A página de contato................................................................................................................ 171 A navegação de páginas ......................................................................................................... 172 Listagem 60 – Navegação das páginas em faces-config.xml ............................................... 174 Alterando os menus ................................................................................................................ 177 Listagem 61. Os métodos dos links do menu Principal ...................................................... 177 Listagem 62. Os métodos dos links do menu Administrativo ............................................ 177 Configurando um Pool para a conexão ................................................................................ 178 Trabalhando com cache de objetos ...................................................................................... 179 Listagem 63. O arquivo persistence.xml .............................................................................. 179 Listagem 64. O arquivo persistence.xml completo.............................................................. 180 Listagem 65. O arquivo ehcache.xml completo ................................................................... 182 Listagem 66. A entidade Autor ............................................................................................. 183 Listagem 67. A entidade Livro .............................................................................................. 184 Listagem 68. A entidade Editora .......................................................................................... 184 Listagem 69. A entidade Publicacao ..................................................................................... 184 Listagem 70. A entidade Usuario .......................................................................................... 185 

O MYSQL ....................................................................................................................................... 186 

O que é um banco de dados relacional? ................................................................................... 186 Instalando o banco de dados ................................................................................................. 186 Instalando no Windows ......................................................................................................... 186 Instalando o MySQL no Linux ............................................................................................. 187 Acessando o banco de dados MySQL ................................................................................... 187 

Page 7: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

77

Comandos essenciais para o uso do MySQL ....................................................................... 188 Alterando tabelas existentes .................................................................................................. 189 

Utilizando índices ....................................................................................................................... 190 Tipos de tabelas .......................................................................................................................... 191 Tipo de dados .............................................................................................................................. 193 Modificadores AUTO_INCREMENT, UNSIGNED e ZEROFILL ...................................... 194 Tipos de caractere ou de dados de string ................................................................................. 195 Tipos variados ............................................................................................................................ 195 Tipos de data e hora (DATE/TIME) ........................................................................................ 196 Modificadores adicionais de coluna ......................................................................................... 196 Sintaxe básica da SQL ............................................................................................................... 197 Funções que trabalham com a instrução SELECT................................................................. 198 Comando UPDATE ..................................................................................................................... 200 Comando DELETE ..................................................................................................................... 200 Trabalhando com Junções ........................................................................................................ 200 Criando uma junção com INNER JOIN ................................................................................... 200 Chaves variadas do MySQL ..................................................................................................... 200 O que é uma chave? .................................................................................................................... 200 Como as chaves funcionam ........................................................................................................ 200 Benefícios de usar uma chave .................................................................................................... 201 Suporte de chaves do MySQL ..................................................................................................... 201 Chaves primárias (Primary Key) ................................................................................................ 201 Chaves estrangeiras (Foreign Key) ............................................................................................ 202 Excluindo uma chave estrangeira .............................................................................................. 202 Administrando o MySQL .......................................................................................................... 202 Entendendo o sistema de privilégios do MySQL ........................................................................ 202 Configurando usuários ............................................................................................................... 202 Confirmando o novo usuário ...................................................................................................... 203 Revogando privilégios ................................................................................................................. 203 Obtendo informações com SHOW ............................................................................................. 203 

Page 8: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

88

Sobre o conteúdo destes Capítulos Embora o livro aborde uma boa parte da técnica necessária para o desenvolvimento com aplicações Web envolvendo o NetBeans IDE, alguns iniciantes sentirão necessidade de um conteúdo mais aprofundado, com exemplos mais complexos e completos, finalizando assim seus estudos.

Esta é a idéia destes capítulos extras, que juntos formam um novo livro, mas com seu conteúdo atrelado ao livro impresso. Isso significa, em prática, que parte do abordado aqui, possui suas explicações técnicas no livro impresso. Em outras partes, códigos são apresentados apenas com pequenos trechos, necessitando do livro para completá-los e conseqüentemente entendê-los.

Com tudo isso, quem ganha é você, caro leitor, que possui em suas mãos um poderoso brinde, que está sendo dado para melhorar e ampliar seus exemplos, sem custo a mais por isso.

Espero que goste deste brinde e que seja muito útil no seu desenvolvimento sobre aplicações escritas em Java para a Web.

Bons códigos,

Edson Gonçalves Autor do livro Desenvolvendo Aplicações Web com NetBeans IDE 6

Page 9: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

99

Capítulo Extra 1 

Trabalhando com Tomcat 5.5  Este capítulo foi escrito para os usuários que utilizam o Tomcat na versão 5.5. Será detalhado desde como inserir o servidor até como utilizar o Administration Tool.

Adicionando na IDE o Tomcat 5.5 Para adicionar o Tomcat 5.5 no NetBeans IDE, clique com o direito do mouse sobre o item Servers na janela Services. Selecione no menu de contexto o item Add Server. Na caixa de diálogo Add Server Instance selecione em Server o Tomcat 5.5. Se preferir alterar o nome contido no campo Name, basta digitar. Clique no botão Next para prosseguir.

Figura 1– Adição do Servlet Container Tomcat 5.5 Na segunda etapa, no campo Catalina Home, clique no botão Browse e selecione o local de instalação do Tomcat 5.5. Digite o nome de usuário no campo Username e a senha em Password. Confirme no botão Finish.

Page 10: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

1010

Figura 2 – Configuração do local de instalação e informações da conta administradora Atenção: Uma adição como esta não habilita automaticamente a opção do Monitor HTTP. Será necessário ir até as propriedades e marcar Enable HTTP Monitor.

Figura 3 – Tomcat 5.5 adicionado no NetBeans

Acessando o administrador na IDE Para acessar o administrador do Tomcat, a aplicação batizada de Admin, clique novamente com o direito do mouse sobre o servidor e selecione no menu de contexto o item View Admin Console. Uma janela do browser se abrirá e você terá uma tela similar a Figura 4:

Page 11: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

1111

Observação: O Administration Tool não vem instalado por padrão no Tomcat 5.5. Será necessário baixá-lo e instalá-lo para então utilizar. 1

Figura 4 – Tela inicial de login do Tomcat Web Server Administration Tool O login e a senha desta aplicação estão em um arquivo chamado de tomcat-users.xml. Este arquivo está no diretório da sua instalação, em: conf. Ao abrir o arquivo, um simples XML, você encontrará a seguinte linha: <user username="admin" password="admin" roles="manager,admin"/> Caso desejar, pode alterar a senha, que está no atributo password. O usuário se encontra em username. Após alterar, você precisará informar a IDE o novo login e senha. Para isso, clique com o direito do mouse novamente sobre o Tomcat, na janela Services. Selecione no menu de contexto o item Properties. Na caixa de diálogo Servers você seleciona o Tomcat 5.5, caso não esteja selecionado em Servers e em Username você adiciona o novo usuário e a senha em Password. Perceba também que é neste local em que você pode alterar as portas do Tomcat. O padrão de uma instalação do Tomcat, fora da IDE é 8080. Após alterar basta clicar no botão Close para confirmar a caixa de diálogo.

1 Recomendo a leitura do livro Tomcat – Guia Rápido do Administrador – Ciência Moderna - 2006

Page 12: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

1212

Figura 5 – Caixa de diálogo Servers com o Tomcat 5.5 selecionado Existem casos em que você precisará fazer o undeploy diretamente pelo administrador. Isso geralmente ocorre quando a IDE não consegue fazê-lo. Para fazer no Tomcat, na aplicação Admin, expanda o nó de Service e clique em Host (localhost).

Figura 6 – Selecionando Host

Page 13: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

1313

No Frame direito, você verá uma caixa de seleção em Host Actions. Clique em Available Actions e selecione Delete Existing Contexts.

Figura 7 – Excluindo um contexto existente O frame exibirá Delete This Context. Selecione o contexto que deseja excluir, em Delete, simplesmente checando o item e clique no botão Save.

Figura 8 – Selecionando o contexto que será removido Para refletir as alterações feitas no Tomcat, através do NetBeans, volte a janela Services e com o direito do mouse sobre o Tomcat 5.5 selecione o item Refresh no menu de contexto. Você também pode clicar com o direito do mouse sobre Web Applications onde apenas um item, o Refresh, aparecerá.

Page 14: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

1414

Figura 9 – Refletindo as alterações no NetBeans

Configurando Pool de Conexões no Tomcat 5.5 pelo Admin Na janela Services, com o Container Servlet Tomcat 5.5 em execução, clique com o direito do mouse e selecione o item View Admin Console. Entre com seu login e senha na área administrativa. Dentro do administrador, no frame esquerdo, expanda o nó Resources e clique em Data Sources. Em Data Source Actions, no menu drop down, selecione Create New Data Source.

Figura 10 – Criando um novo Data Source pelo Admin do Tomcat 5.5 Preencha os campos de Data Source como mostrado na Figura 11 a seguir e salve as alterações clicando no botão Save.

Page 15: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

1515

Figura 11 – Data Source configurado

Utilizando JNDI no arquivo persistence.xml Para trabalhar com JPA, aqui há os passos de como utilizar o JNDI em seu arquivo de persistência. No NetBeans abra o arquivo persistence.xml, no seu projeto que utiliza o Tomcat, e coloque em XML. Altere o XML do arquivo para o mostrado na Listagem 1 a seguir: Listagem 1. Alteração do arquivo persistence.xml ... <persistence-unit name="livraria"> <non-jta-data-source> java:comp/env/jdbc/livraria </non-jta-data-source> <class>br.com.integrator.Autor</class> <class>br.com.integrator.Livro</class> <properties> <property name="toplink.session.customizer" value="br.com.integrator.util.JPAToplinkSessionCustomizationUtil"/> <property name="toplink.logging.level" value="INFO"/> </properties> </persistence-unit> ... Um típico caso de uma transação JTA, utilize um elemento chamado de <jta-data-source/> no qual você especifica o JNDI do acesso ao banco de dados. Similarmente em uma transação do tipo resource-local, na unidade de persistência o elemento <non-jta-data-source /> é usado.

Page 16: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

1616

<non-jta-data-source> java:comp/env/jdbc/livraria </non-jta-data-source> Nos elemento <properties/> você tem dois elementos <property/>, onde um contém uma chamada a uma classe que persistirá a sessão. Dentro do pacote br.com.integrator.util, crie uma classe, que se chamará de JPAToplinkSessionCustomizationUtil. Adicione o código da Listagem 2 a seguir nesta classe: Listagem 2. A classe JPAToplinkSessionCustomizationUtil

... public class JPAToplinkSessionCustomizationUtil implements SessionCustomizer { public void customize(Session session) throws Exception{ JNDIConnector connector = (JNDIConnector)session.getLogin( ).getConnector( ); connector.setLookupType(JNDIConnector.STRING_LOOKUP); } } Fixe as importações com Ctrl + Shift + I. Não se esqueça de adicionar o Resource References do seu JNDI no deployment descriptor.

Page 17: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

1717

Capítulo Extra 2 

Aplicações Web com acesso a dados sem padrão  Este capítulo foi escrito para desenvolvedores iniciantes que estão começando com aplicações Web em Java e desejam aprender o básico antes de iniciar o trabalho com padrões de desenvolvimento como MVC e DAO.

Desenvolvendo via JDBC sem padrões Para começar, uma breve revisão de como adicionar uma biblioteca JDBC, caso você não tenha a do banco de dados que vai utilizar. Para o exemplo, será utilizado o MySQL, por estar sendo abordado ao longo do livro.

Criando o projeto Crie um novo projeto no NetBeans e o chame de TrabComJDBCeMySQL. No seu projeto gerado, clique com o direito do mouse sobre o item Libraries. No menu de contexto, você possui as opções para escolher:

1. Add Library - Adiciona uma biblioteca configurada no NetBeans IDE. 2. Add JAR/Folder - Adicione um JAR ou Diretório em apenas um projeto da IDE. 3. Add Project – Adiciona um projeto e conseqüentemente suas dependências.

Figura 1 – Adicionando uma nova biblioteca Selecione a opção Add Library no menu de contexto. Na caixa de diálogo Add Library clique no botão Manage Libraries.

Page 18: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

1818

Figura 2 – Adicionando uma nova biblioteca Na caixa de diálogo Library Manager clique no botão New Library. Digite MySQL em Library Name, na caixa de diálogo New Library. Selecione Class Libraries, em Library Type, caso não esteja selecionado e clique no botão OK para confirmar.

Figura 3 – Criando uma nova biblioteca no NetBeans

Page 19: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

1919

Voltando a caixa de diálogo Library Manager, com a biblioteca MySQL criada, selecionada em Libraries, clique no botão Add JAR/Folder e selecione a biblioteca JDBC do MySQL e depois confirme a caixa de diálogo.

Figura 4 – Adição do arquivo JAR Selecione em Add Library a biblioteca MySQL adicionada e clique no botão Add Library.

Figura 5 – Adicionando a biblioteca ao projeto Voltando em seu projeto, você deverá ver a biblioteca MySQL adicionada em seu projeto.

Page 20: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

2020

Figura 6 – Biblioteca JDBC do MySQL adicionada ao projeto

Conectando sua página JSP ao banco de dados Para que você entenda como funciona a conexão e a leitura de dados de um banco de dados, altere a página index.jsp adicionando os códigos da Listagem 1 a seguir, para trabalhar com o MySQL. Listagem 1. Alterações na página index.jsp <%@page contentType="text/html"%> <%@page pageEncoding="ISO-8859-1" import="java.sql.*" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Conectando sua aplicação JSP ao MySQL via JDBC</title> </head> <body> <table border="1"> <thead> <tr> <th>ID</th><th>Título</th> </tr> </thead> <tbody> <% Connection conn = null; Statement st = null; ResultSet rs = null; try { Class.forName("com.mysql.jdbc.Driver").newInstance( ); conn = DriverManager.getConnection( "jdbc:mysql://localhost/livraria", "edson","integrator"); st = conn.createStatement( ); rs = st.executeQuery("select id, titulo from livros"); while(rs.next( )) { %>

Page 21: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

2121

<tr> <td><%= rs.getString("id") %></td> <td><%= rs.getString("titulo") %></td> </tr> <% } //end while } catch (Exception ex) { ex.printStackTrace( ); } finally { if (rs != null) rs.close( ); if (st != null) st.close( ); if (conn != null) conn.close( ); } %> </tbody> </table> </body> </html> Dentro do bloco try...catch você define o trabalho com o banco de dados para se conectar e executar a instrução SQL. Ao importar o pacote java.sql.*, através da diretiva page, você tem acesso às classes e interfaces para manipular os bancos de dados relacionais em Java. O driver de banco de dados deve ser empregado antes do programa se conectar ao banco de dados. A linha anterior utiliza o método static forName da classe Class (pacote java.lang) para carregar a definição de classe para o driver de banco de dados. Se a classe não for localizada, ele dispara uma exceção: java.lang.ClassNotFoundException. Um objeto Connection gerencia a conexão entre o programa Java e o banco de dados. Ele também fornece suporte ao programa para executar instruções SQL. Através do método static getConnection, a classe DriverManager tenta uma conexão com o banco de dados especificado pela string: jdbc:mysql://localhost/livraria. Os argumentos seguintes são o nome de usuário e a senha, demonstrados pela String edson e integrator respectivamente. Caso a classe DriverManager não conseguir se conectar ao banco de dados, o método getConnection dispara uma exceção: A responsabilidade principal da interface Statement é executar sentenças SQL no banco de dados. Com o método público createStatement você cria um objeto Statement para enviar declarações SQL ao banco de dados. Se houver um erro, dispara também a exceção java.sql.SQLException. Com o método executeQuery, você tem o retorno de um objeto que implementa ResultSet e que contém os resultados da consulta. Através de um loop while você varre os resultados encontrados, onde o método next( ), de ResultSet, retorna um valor booleano true, quando o resultado das linhas pesquisadas na query forem exauridas. O método getString( ), de ResultSet, traz o valor da coluna designada na fila atual deste ResultSet como uma String na linguagem Java. Depois de consumidos, os recursos devem ser retornados ao servidor, utilizando o método close( ). Nesse caso a cláusula usada é finally, que liberará os recursos, caso os resultados sejam bem sucedidos ou não.

Page 22: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

2222

Figura 7 – Exibição dos livros cadastrados

Inserindo dados O exemplo que será feito irá ilustrar a inserção de dados no banco de dados. Você terá em uma página JSP, um formulário HTML comum, sem código dinâmico, contendo os campos necessários para inserir. Esse formulário irá enviar os dados, via método POST, para outra página JSP, que recuperará essas informações e as enviará para o banco de dados MySQL. Crie uma nova página JSP e a chame de formInserindoDados.jsp. Altere-a como mostra a Listagem 2 a seguir. Listagem 2. Alterações na página formInserindoDados.jsp <%@page contentType="text/html"%> <%@page pageEncoding="ISO-8859-1"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Inserindo Dados</title> </head> <body> <form action="inserindoDados.jsp" method="post"> <table> <tr> <td>Título:</td> <td><input type="text" name="titulo" /></td> </tr> <tr> <td>Edição:</td> <td><input type="text" name="edicao" /></td> </tr> <tr> <td>Publicação:</td> <td><input type="text" name="publicacao" /></td> </tr> <tr> <td>Descrição:</td> <td> <textarea name="descricao" rows="5" cols="25"></textarea> </td> </tr> <tr> <td colspan="2">

Page 23: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

2323

<input type="submit" name="btCadastrar" value="Enviar" /> </td> </tr> </table> </form> </body> </html> Como essa é uma página simples com um formulário básico contendo apenas conteúdo HTML, não haverá comentários sobre o mesmo.

Figura 8 – Formulário de cadastro A página JSP que irá receber esses valores será chamada de inserindoDados.jsp e é mostrada a na Listagem 3 a seguir: Listagem 3. Alterações na página inserindoDados.jsp <%@page language="java" contentType="text/html;" pageEncoding="ISO-8859-1" import="java.sql.*" %> <% String titulo = request.getParameter("titulo"); String edicao = request.getParameter("edicao"); String publicacao = request.getParameter("publicacao"); String descricao = request.getParameter("descricao"); Connection conn = null; PreparedStatement pst = null; try { Class.forName("com.mysql.jdbc.Driver").newInstance( ); conn = DriverManager.getConnection("jdbc:mysql://localhost/livraria", "edson","integrator"); String SQL = "INSERT INTO livros (titulo, edicao, " + "publicacao, descricao) " + "values (?, ?, ?, ?)"; pst = conn.prepareStatement(SQL); pst.setString(1, titulo); pst.setInt(2, Integer.parseInt(edicao)); pst.setString(3, publicacao);

Page 24: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

2424

pst.setString(4, descricao); pst.executeUpdate( ); pst.clearParameters( ); } catch (Exception ex) { ex.printStackTrace( ); } finally { if (pst != null) pst.close( ); if (conn != null) conn.close( ); } %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Inserindo Dados</title> </head> <body> <h3>O Livro <%=titulo %> foi inserido com sucesso!</h3> </body> </html>

Figura 9 – Cadastro inserido A interface PreparedStatement tem um papel semelhante à interface Statement, o que nos permite executar sentenças SQL sobre uma conexão estabelecida com um banco de dados. Porém, neste caso, você utiliza sentenças mais especializadas, como a de inserir dados, onde você pode receber vários parâmetros como entrada. Um parâmetro de entrada é aquele cujo valor não se especifica quando a sentença é criada. No seu lugar a sentença recebe um sinal de interrogação (?) para cada parâmetro de entrada. Antes de executar a sentença, você deve especificar um valor para cada parâmetro, através dos métodos set apropriados. Para criar um objeto PreparedStatement você deve lançar um método prepareStatement(String s) da interface Connection sobre o objeto que representa a conexão estabelecida com o banco de dados. Através do método setString(int i, String s) , você prepara os dados que estão vindo dos campos do seu aplicativo para inserir no banco de dados. Como você mesmo já concluiu, o tipo string foi utilizado graças ao tipo existente no banco de dados.

Page 25: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

2525

O método setInt(int i, int i) faz o mesmo que o anterior, mas exige um valor inteiro. Com o método executeUpdate( ) você executa a sentença SQL para o tipo, que no caso é de inserção (INSERT). Esse método também serve para os atualizações (UPDATE) e exclusões (DELETE). Após utilizar os métodos setter, você pode limpá-los usando o método clearParameters( ) .

Entendendo os principais Statements Como você viu, Statements são essenciais para se comunicar com uma base de dados que usa a linguagem SQL. Há três principais tipos de Statements. O primeiro é a interface Statement. Quando são criados objetos pela implementação da interface Statements , estes são geralmente usados para executar declarações SQL genéricas que não levam qualquer parâmetro. O segundo tipo é o PreparedStatement que herda da interface Statement. Objetos PreparedStatement são úteis quando você precisar criar e compilar declarações SQL antes do tempo. Objetos PreparedStatement também aceitam parâmetros IN. O tipo final de statement é o CallableStatement. O CallableStatement herda de PreparedStatement e aceita parâmetros IN e OUT. Seu propósito principal é executar procedimentos armazenados de banco de dados.

Explorando a interface PreparedStatement Se você precisar executar declarações SQL muitas vezes, o PreparedStatement é a escolha perfeita para essa tarefa, isso porque aumenta a eficiência e desempenho do programa. O PreparedStatement é a escolha lógica do nome para a interface porque contém uma declaração SQL que previamente foi compilada e enviada ao DBMS de sua escolha, por isso o termo prepared. O PreparedStatement dá o desenvolvedor que a habilidade de embutir parâmetros na declaração SQL contidos no objeto PreparedStatement. Estes parâmetros IN (de entrada) são denotados na declaração SQL pelo símbolo de interrogação (?). A Tabela 1 mostra os métodos setters que indicam os tipos para PreparedStatement: Tabela 1 – Métodos setters para PreparedStatement Método void Descrição setBoolean(int paramIndex, boolean b) Parâmetro de entrada com valor booleano. setDate(int paramIndex, Date d) Parâmetro de data de entrada. Deve ser um valor

java.sql.Date. setDouble(int paramIndex, double d) Parâmetro de entrada com valor double.

setFloat(int paramIndex, float f) Parâmetro de entrada com valor float.

setInt(int paramIndex, int i) Parâmetro de entrada com valor int.

setLong(int paramIndex, long l) Parâmetro de entrada com valor long. setString(int paramIndex, String s) Parâmetro de entrada com valor String.

clearParameters( ) Limpa os parâmetros enviados pelos métodos setters.

A biblioteca de tags SQL do JSTL Embora seja desencorajado o uso de tags SQL da biblioteca JSTL em aplicações de páginas JSP, você apenas conhecerá um exemplo de seu uso.

Page 26: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

2626

Crie um novo projeto e adicione a biblioteca JSTL junto a biblioteca MySQL.

A action <sql:setDataSource /> As ações fornecidas pela tag da biblioteca SQL operam em uma fonte de dados definida pela classe java.sql.DataSource. A action <sql:setDataSource /> configura uma fonte de dados e transmite essa informação através do atributo var, em uma fonte de dados criada no escopo da página ou em dataSource para uma fonte de dados física. A fonte de dados configurada é usada pelas actions restantes da biblioteca SQL que pode executar as instruções já conhecidas. Você pode configurar o data source da seguinte forma: <sql:setDataSource var="dataSource"

driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/livraria" user="edson" password="integrator"/>

Tabela 2 – Atributos e descrição da action <sql:setDataSource/> Atributo Descrição

driver O nome da classe JDBC que será usada.

scope A variável de escopo definida pelo atributo var. Por padrão esse atributo é page.

url O URL do data source.

user O usuário para acessar o banco de dados configurado no atributo url.

password A senha para acessar o banco de dados configurado no atributo url.

var A variável de escopo criada para acessar o data source em outras actions.

O data source também pode ser definido como: <sql:setDataSource dataSource="jdbc/LivrariaDB"/> Como você pode ver, é possível fornecer um caminho relativo a um recurso Java Naming and Directory Interface (JNDI) pelo atributo opcional dataSource. Se você tiver um nome JNDI para o dataSource, então o atributo dataSource acessará pela página JSP a fonte de dados JNDI. Neste caso, você não precisa fornecer quaisquer um dos demais atributos, porque eles já são fornecidos como parte do recurso acessado pelo JNDI.

A action <sql:query /> A action <sql:query /> fornece a funcionalidade de executar queries do tipo SELECT: <sql:query var="livros" dataSource="${dataSource}" > SELECT * FROM livros

Page 27: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

2727

</sql:query> O exemplo da Listagem 4 demonstra o uso da conexão e da execução de uma query com as tags SQL do JSTL: Listagem 4. Alterações na página inserindoDados.jsp <%@page contentType="text/html"%> <%@page pageEncoding="ISO-8859-1"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Usando instruções SQL com JSTL</title> </head> <body> <sql:setDataSource var="dataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/livraria" user="edson" password="integrator" /> <sql:query var="livros" dataSource="${dataSource}"> SELECT * FROM livros </sql:query> <table border="1"> <tr> <th>ID</th> <th>Título</th> </tr> <c:forEach var="row" items="${livros.rows}"> <tr> <td><c:out value="${row.id}" /></td> <td><c:out value="${row.titulo}" /></td> </tr> </c:forEach> </table> </body> </html> Os cabeçalhos são definidos na diretiva taglib, como já vista anteriormente. A URI do primeiro cabeçalho chama as tags CORE e o segundo cabeçalho são as tags de SQL. O prefixo usado é a letra "sql", que é um padrão definido pela Sun. <%@taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>

O data source é definido nesse caso com a conexão feita diretamente na página. Não se esqueça de que é necessário colocar o .jar da ponte JDBC do MySQL no diretório lib de WEB-INF. <sql:setDataSource var="dataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/livraria" user="edson" password="integrator" /> A query é criada, nesse caso selecionando todos os registros encontrados na tabela livros.

Page 28: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

2828

<sql:query var="livros" dataSource="${dataSource}"> SELECT * FROM livros </sql:query> Com a action <c:forEach /> você tem uma varredura dos resultados encontrados dentro da tabela livros, resultantes da SELECT. Dentro do atributo items você determina a variável livros usando a EL e separando por um "." ponto seguido da palavra rows. <c:forEach var="row" items="${livros.rows}"> Os resultados são exibidos utilizando-se a EL contendo a variável determinada no atributo var existente na action <c:forEach />, separado por ponto “.” e o nome da coluna a ser exibida. <td><c:out value="${row.isbn}" /></td> O resultado é similar ao exibido no exemplo dado com a página JSP.

Page 29: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

2929

Capítulo Extra 3 

Struts Framework  Este capítulo extra o instruirá no desenvolvimento com Struts Framework utilizando o NetBeans IDE 6. O Struts se encontra atualmente na versão 2, que até o momento em que este livro é escrito, não há um suporte direto pela IDE. A versão que suportada pelo NetBeans, do Struts, é 1.2.9, a que será tratada neste capítulo.

A origem do Struts Framework Jakarta Struts é um framework open source, escrito em Java, de desenvolvimento Web, mantido pela Apache Software Foundation (ASF). O framework Struts foi criado por Craig R. McClanaham e doado para a ASF no ano 2000. Como implementação do paradigma MVC (Model-View-Controller), utilizando um padrão similar ao Model 2, esse framework é um dos mais populares entre os desenvolvedores.

Seu primeiro projeto com Struts Seguindo um padrão tradicional da IDE, o suporte a Struts é pouco visual, ou seja, existem poucos assistentes que o auxiliarão no trabalho com este Framework. Partindo deste princípio, o primeiro exemplo será pequeno para que você compreenda as principais características do desenvolvimento de Struts com o NetBeans IDE. Comece criando uma aplicação Web comum. Digite o nome do seu projeto, que no caso do livro será PrimProjStruts e selecione como Server o Tomcat. Clique no botão Next.

Figura 1 – Criando um projeto com Struts Na última etapa do assistente, não utilizada até o momento no livro, no desenvolvimento de aplicações web, você encontra os dois frameworks padrão existentes no NetBeans IDE. Selecione o Framework Struts, marcando a opção Struts 1.2.9.

Page 30: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

3030

Observe que o campo Action Servlet Name já contém uma configuração que não pode ser alterada. Em Action URL Pattern você percebe a extensão criada, que no caso seguiremos o padrão *.do. Altere o pacote já preenchido no campo Application Resource para br.com.integrator.struts.ApplicationResource (ou o nome do pacote que desejar.struts.ApplicationResource) e clique no botão Finish.

Figura 2 – Seleção e configuração em web.xml do framework Struts na terceira etapa Ao concluir o projeto, você perceberá que o NetBeans IDE criou em Web Pages duas páginas: index.jsp (o padrão até o momento) e welcomeStruts.jsp. Ao expandir o nó de Libraries, você notará que existem as bibliotecas necessárias para o desenvolvimento de Struts em suas páginas.

Page 31: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

3131

Figura 3 – Bibliotecas do Struts sendo exibida em Libraries Para uma aplicação que utilize o framework Struts, o NetBeans IDE adiciona oito arquivos do tipo JAR:

1. commons-beanutils.jar 2. commons-fileupload.jar 3. commons-digester.jar 4. commons-logging.jar 5. commons-validator.jar 6. antlr.jar 7. jakarta-oro.jar 8. struts.jar

Em um ambiente de produção, estas bibliotecas devem estar disponíveis em sua aplicação no diretório lib, encontrado em WEB-INF.

As camadas de Struts Uma vez que o Struts trabalha dentro do paradigma MVC, você vai analisar cada camada em um pequeno exemplo para entendê-lo melhor. Esta aplicação será uma classe que receberá um nome vindo de um formulário.

A camada Modelo Crie um novo arquivo no NetBeans IDE, selecione na caixa de diálogo em Categories o item Struts e em File Types o item Struts ActionForm Bean. Clique no botão Next para prosseguir.

Page 32: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

3232

Figura 4 – Seleção do tipo de arquivo Struts ActionForm Bean Na segunda e última etapa, coloque NomeForm em Class Name e em Package escreva o nome do seu pacote (seguindo o livro: br.com.integrator). Clique no botão Finish para concluir.

Figura 5 – Nome da classe ActionForm e do pacote

Page 33: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

3333

A classe gerada pelo NetBeans IDE contém uma pré-configuração que o ajudará a desenvolver o exemplo. Nesta classe, altere o atributo name criado, utilizando refactor. Clique com o direito do mouse sobre este atributo e selecione no menu de contexto o item Refactor e clique em Rename. Na caixa de diálogo Rename Field digite nome em New Name. Desmarque a opção Preview All Changes (caso esteja marcada) e clique no botão Next para concluir.

Figura 6 – Refatorando o atributo name Apague os métodos acessores do anterior e refaça novamente (get e set do atributo nome). Altere o método validate(), como mostrado a seguir, em destaque, na Listagem 1 do código da classe NomeForm: Listagem 1. Alterações na classe NomeForm package br.com.integrator; import javax.servlet.http.HttpServletRequest; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionMessage; public class NomeForm extends org.apache.struts.action.ActionForm { private String nome; public String getNome() { return nome; } public void setNome(String string) { nome = string; } public NomeForm() { super(); } //método que retorna um erro de validação caso nome não seja preenchido no formulário public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors errors = new ActionErrors(); if (getNome() == null || getNome().length() < 1) { errors.add("nome", new ActionMessage("errors.required")); } return errors; } }

Page 34: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

3434

A classe NomeForm estende org.apache.struts.action.ActionForm, no qual trata eventos de formulário. Para cada campo em um formulário HTML, há uma variável com métodos getters e setters no bean Form para capturá-lo. O controller Struts popula o formulário HTML chamando os métodos getters no bean Form. Quando o usuário submete o formulário, o controller Struts injeta informações no bean Form com dados vindos deste formulário HTML, chamando métodos setters na instância do bean Form. Com o método validate( ) você retorna um objeto ActionErrors. A classe ActionErrors encapsula um ou mais erros que são encontrados pela aplicação. Os problemas encontrados são representados pela instância de org.apache.struts.action.ActionError. Para mostrar a mensagem ao usuário, uma classe é chamada para isso. A classe org.apache.struts.action.ActionMessage opera da mesma maneira que a classe ActionError. Na realidade, a classe ActionMessage foi acrescida como superclasse à ActionError.

As mensagens enviadas ao usuário Na janela Projects expandas os nós de Source Packages e do pacote br.com.integrator.struts. No arquivo ApplicationResource.properties clique com o direito do mouse e selecione o item Open no menu de contexto. Remova os key-values existentes mantendo apenas os mostrados na Figura 7 a seguir:

Figura 7 – Alterações no arquivo ApplicationResource.properties Em Value da Key errors.required altere para “O Campo Nome é obrigatório”. Salve e feche o arquivo. Estes textos alterados, encontrados no arquivo ApplicationResource.properties, são usados pela tag Struts <html:errors />, na página que ainda será desenvolvida. São textos que podem ser personalizados e, portanto, poderá conter as informações que desejar. Você também pode adicionar tags HTML se preferir dar um formato melhor nos textos de saída gerados pelas páginas Struts, como feito em errors.header, errors.prefix, errors.suffix e errors.footer.

Page 35: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

3535

Criando a ação em Struts A ação em Struts será a responsável pela recuperação do nome digitado pelo usuário e a interação com a camada Modelo. Sua responsabilidade é dar navegação e Controle para a camada Apresentação. Crie um novo arquivo onde, na caixa de diálogo, em Struts, selecione Struts Action em File Types e prossiga.

Figura 8 – Criando um novo arquivo do tipo Struts Action Na segunda etapa, digite ControleAction no campo Class Name. O pacote será br.com.integrator (ou o que está usando). Em Action Path digite /NomeForm e clique no botão Next.

Page 36: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

3636

Figura 9 – Criando a classe ControleAction Na última etapa defina no campo Input Resource, clicando no botão Browse, a seleção da página welcomeStruts.jsp. Em Scope selecione o botão de rádio Request. Termine o assistente clicando no botão Finish.

Figura 10 – Configuração para o bean ActionForm Na classe ControleAction gerada, e deixe seu código similar ao mostrado na Listagem 2 a seguir.

Page 37: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

3737

Listagem 2. Alterações na classe ControleAction package br.com.integrator; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionForward; public class ControleAction extends org.apache.struts.action.Action { /* forward name="success" path="" */ private final static String SUCCESS = "success"; /** * This is the action called from the Struts framework. * @param mapping The ActionMapping used to select this instance. * @param form The optional ActionForm bean for this request. * @param request The HTTP Request we are processing. * @param response The HTTP Response we are processing. * @throws java.lang.Exception * @return */ public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { String nome = (String) PropertyUtils.getSimpleProperty(form, "nome"); MeuBeanModelo mb = new MeuBeanModelo(); mb.setNome(nome); request.setAttribute(Constante.NOME_KEY, mb); return mapping.findForward(SUCCESS); } } Fixe as importações. Existem dois pontos nesta classe que não poderão ser fixados: uma é o MeuBeanModelo, um Bean que ainda não foi feito e o outro é a constante Constante.NOME_KEY, que está na mesma situação. Não se preocupe que você os fará logo a seguir. Uma classe org.apache.struts.action.Action no framework Struts é uma extensão do componente controller. A classe Action pega o pedido do cliente para o modelo de negócios. Esta mesma classe também pode executar outras funções, como autorização, login e validação de sessão antes de invocar a operação de negócios. A Action Struts contém diversos métodos, mas o mais importante é o execute(). Esse método contém a seguinte assinatura: public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)throws Exception O método execute() é chamado pelo controlador quando um pedido é recebido de um cliente. O controlador cria uma instância da classe Action se ainda não existir. O framework Struts cria somente uma instância de cada classe Action em sua aplicação. Como pode haver muitos usuários, você tem que assegurar que todas suas classes Action operem corretamente em um ambiente de multithreaded, da mesma maneira que faria ao desenvolver um Servlet.

Page 38: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

3838

O mapeamento Action é parte da informação da configuração do Struts, encontrado em um arquivo XML especial. Esta informação configurada é carregada na memória, durante a inicialização, e disponibilizada para o framework em tempo de execução. Este elemento é representado na memória por uma instância da classe org.apache.struts.action.ActionMapping. O objeto ActionMapping contém o atributo path, que é encontrado no arquivo XML da configuração do framework, em contraste a uma porção de URI de pedido entrante. Observe a seguir o trecho listado do arquivo de configuração struts-config.xml da sua aplicação: <action-mappings> <action input="/welcomeStruts.jsp" name="NomeForm" path="/NomeForm" scope="request" type="br.com.integrator.ControleAction"/> <action path="/Welcome" forward="/welcomeStruts.jsp"/> </action-mappings>

Para que seja determinada para onde serão enviados os dados, você precisa utilizar o método findForward(). Na assinatura do método execute() da classe Action, você deve ter notado que o tipo de retorno para o método é uma classe org.apache.struts.action.ActionForward. A classe ActionForward representa um destino para o qual o controlador pode retornar uma vez que a Action foi completa. A action forward é especificada no arquivo de configuração XML do framework Struts (struts-config.xml), similar a action mapping. Embora o NetBeans IDE já tenha configurado boa parte das informações contidas no arquivo struts-config.xml, você precisará mapear para onde será enviado os dados preenchidos no formulário caso seja bem sucedido. Com o direito do mouse sobre o trecho mostrado anteriormente, em detalhes na Figura 11, entre os elementos <action />, de struts-config.xml, selecione Struts e clique no item Add Forward.

Figura 11 – Adicionando o elemento <forward /> ao arquivo struts-config.xml

Page 39: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

3939

Na caixa de diálogo Add Forward digite, no campo Forward Name, a palavra success, que como você deve lembrar, é retornado pelo método findForward() da classe ControleAction. No campo Resource File, será colocada a página que receberá os dados enviados pela Action, no qual será chamada de sucesso.jsp. Esta página ainda não foi criada, portanto não será possível selecioná-la (apenas digite seu nome neste campo). A Figura 12 a seguir demonstra o resultado final de sua caixa de diálogo.

Figura 12 – Configuração do elemento <forward /> através do diálogo Add Forward Ao clicar no botão Add para confirmar, perceba que o elemento <forward /> é adicionado ao arquivo struts-config.xml. Os atributos name e path foram adicionados com as informações transmitidas pela caixa de diálogo.

Figura 13 – Situação final dos elementos encontrados em <action-mappings/> Para transmitir o nome digitado para a outra página, o método getSimpleProperty() da classe PropertyUtils recebe do formulário o conteúdo do campo nome, como você o adicionou na classe ControleAction: String nome = (String) PropertyUtils.getSimpleProperty(form, "nome");

Page 40: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

4040

Para que se possa recuperar a informação enviada pelo formulário, um bean será criado para persistir a informação passada para outra página. O bean será chamado de MeuBeanModelo e conterá apenas a possibilidade de captar e transmitir o nome digitado no formulário que será criado na página JSP utilizando Struts. Crie uma classe chamada de MeuBeanModelo e a coloque dentro do pacote br.com.integrator (ou o principal que estiver utilizando em seu projeto).

Figura 14 – Criação do bean MeuBeanModelo O bean que criado é apenas para dar o acesso ao atributo nome, no qual será enviado pela Action e recuperada pela página sucesso.jsp, exibindo assim os dados encontrados. Altere a classe MeuBeanModelo como mostrado na Listagem 3 a seguir: Listagem 3. Alterações na classe MeuBeanModelo package br.com.integrator; public class MeuBeanModelo { private String nome; public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public MeuBeanModelo() { } }

Passando dados para a camada de apresentação Como já dito, a classe ControleAction passa o valor recebido pelo campo nome, do formulário, para a próxima página, que ainda será criada, através do método setAttribute().

Page 41: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

4141

request.setAttribute(Constante.NOME_KEY, mb); Quando se passa um objeto de ActionClass para o componente encontrado na View (uma página JSP) usando request.setAttribute(), você precisa fornecer um nome, ou identificador String que o arquivo JSP possa usar para recuperar o objeto. Para isso, crie uma classe Java, chamada de Constante, coloque-a no pacote principal (br.com.integrator) e a transforme em uma constante como mostrado na Listagem 4 a seguir: Listagem 4. Alterações na classe Constante package br.com.integrator; public final class Constante { public static final String NOME_KEY = "integrator"; }

O formulário que enviará o nome Como o NetBeans IDE tem o costume de iniciar um projeto com arquivos já pré-configurados, entre no arquivo welcomeStruts.jsp e altere o conteúdo como mostrado na Listagem 5 a seguir: Listagem 5. Alterações na página welcomeStruts <%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%> <%@taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %> <html:html locale="true"> <head> <title>Minha primeira página usando Struts</title> <html:base /> </head> <body> <html:form action="/NomeForm.do" > Nome: <html:text property="nome" size="16" maxlength="16"/> <br /> <html:submit property="submit" value="Enviar"/> </html:form> <p> <html:errors/> </p> </body> </html:html> Assim como ocorre com outras bibliotecas de tags, o Struts é configurado em sua página através da diretiva taglib, onde existem as bibliotecas que manipulam o HTML e outras. No caso, apenas a biblioteca de HTML será necessária. <%@taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %>

Page 42: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

4242

Dentre as tags Struts adicionadas na página, uma em especial, a tag <html:form /> , cria um formulário para envio de dados pelo framework. No atributo action você configura para onde o formulário será enviado, que no caso será NomeForm.do. Lembre-se de que o elemento <action-mappings />, em struts-config.xml, no sub-elemento <action />, foi configurado esse caminho para o envio de dados (veja Figura 13). A tag Struts <html:text /> é a responsável pela geração da caixa de texto que receberá o nome a ser digitado. Através do atributo property você determina o nome da caixa de texto. Com a tag Struts <html:submit /> você cria o botão de envio e seu tipo é determinado pelo atributo property. O atributo value indica o rótulo do botão, como ocorre no HTML comum. Por fim, a tag Struts <html:errors /> que resulta na mensagem de erro trazida pela classe NomeForm.

A página que resulta no sucesso do envio Para finalizar, crie uma nova página JSP chamada de sucesso. Altere-a como mostra a Listagem 6 a seguir: Listagem 6. Alterações na página sucesso.jsp <%@page contentType="text/html"%> <%@page pageEncoding="UTF-8"%> <%@taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> <%@taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> <%@taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html:html> <head> <title>Seja bem vindo</title> </head> <body> <logic:present name="integrator" scope="request"> <h2> <bean:write name="integrator" property="nome" /> </h2> </logic:present> </body> </html:html> Na página que receberá o resultado enviado pelo formulário, você determina se existe uma informação enviada através da tag <logic:present/>, que utiliza seu atributo name para verificar se há a chave integrator. Caso não se lembre, a palavra integrator é a chave transmitida pela constante. public static final String NOME_KEY = "integrator"; Utilizando request.setAttribute( Constante.NOME_KEY, mb) da classe ControleAction. Caso exista, a tag <bean:write /> recupera o valor enviado e o imprime na tela. O resultado de todos esses passos é um pequeno formulário contendo um campo e um botão. Caso não seja digitado nada

Page 43: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

4343

e enviado, o erro aparece logo abaixo do botão, devido ao posicionamento da tag Struts <html:errors/>. Caso contrário, seu nome será enviado com sucesso e exibido na página sucesso.jsp.

Figura 15 – Resultado da página sem o campo preenchido

As tags do Struts As tags do Struts são divididas em cinco bibliotecas:

• html: permite a criação e manipulação de tags HTML com o Struts, principalmente formulários;

• logic: permite a criação de estruturas de condição e repetição, além da administração do fluxo da aplicação;

• bean: permite a criação e manipulação de JavaBeans dentro da página; • nested: permite a definição de modelos de objetos aninhados e a capacidade de representá-

los e administrá-los; • template: permite a criação de modelos dinâmicos de páginas JSP que compartilham de um

formato comum. Destas cinco bibliotecas, aqui você aprenderá mais detalhadamente as três primeiras.

As tags HTML do Struts A biblioteca de tags HTML do Struts contém tags para renderizar o HTML, como o conhecemos. Algumas tags foram apresentadas nas páginas mostradas com exemplo anterior, mas com pouca informação técnica. Agora, para uma melhor compreensão das tags Struts, você terá uma descrição mais detalhada. Estas tags são personalizadas pela biblioteca e facilitam a comunicação com as configurações geradas pelas classes desenvolvidas para esse fim. Essas tags podem ser chamadas através da diretiva taglib existente em uma página JSP: <%@taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> Como pode notar, a biblioteca HTML do Struts é chamada pela URI: http://jakarta.apache.org/struts/tags-html E que contém o prefixo padrão html. A Tabela 1 a seguir demonstra as tags HTML do Struts framework:

Page 44: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

4444

Tabela 1 - Tags HTML do Struts Nome da Tag Descrição base Cria um elemento HTML base button Cria um botão com a tag input cancel Cria um botão cancel checkbox Cria uma caixa de checagem (input checkbox) errors Renderiza mensagens de erros enviados file Cria um campo HTML file form Define um elemento (tag) HTML form frame Cria um elemento HTML frame hidden Cria um campo HTML hidden html Cria um elemento HTML html image Renderiza uma tag input do tipo "image" img Cria uma tag HTML img

javascript Renderiza uma validação JavaScript baseada na validação carregada pelo ValidatorPlugIn

link Cria uma tag HTML anchor ou hyperlink messages Condicionalmente mostra as mensagens transmitidas pela classe multibox Cria múltiplos campos caixa de checagem (input checkbox) option Cria a tag select option options Cria uma coleção de tags select options optionsCollection Cria uma coleção de tags select options password Cria um campo input password radio Cria um botão de radio (input radio) reset Cria um botão reset rewrite Renderiza uma URI select Renderiza uma tag select submit Renderiza um botão submit text Cria uma tag input field do tipo "text" textarea Cria uma tag textarea

A tag form A tag Struts form é uma das mais importantes tags encontradas na biblioteca de tags HTML. É com esta tag que é renderizado a tag padrão form do HTML e, em conjunto, criado um direcionamento com a ActionForm configurada para a aplicação. Como a tag <html:form />, o Struts controla aspectos importantes de uma página. A Tabela 2, a seguir, contém os elementos nela existentes:

Page 45: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

4545

Tabela 2 - Os atributos da tag Struts <html:form /> Nome do atributo Descrição action A URL para o qual o formulário será submetido enctype O content encoding para o qual será usado na submissão do formulário. focus O nome do campo no qual haverá um foco inicial. method O método HTTP no qual será usado para submeter os dados.

name O nome da ActionForm do qual as propriedades serão usadas para popular os valores dos campos input.

onreset Tratador de evento JavaScript executado se o formulário é reiniciado. onsubmit Tratador de evento JavaScript executado se o formulário for submetido. scope O escopo da ActionForm para este formulário. style Os estilos CSS para ser aplicado nas tags HTML desse elemento. styleClass Classe CSS para ser aplicado neste elemento HTML. styleId O identificados para a assinatura deste elemento HTML.

target O alvo para acessar um determinado frame quando o formulário for submetido.

type O nome de classe completamente qualificado de ActionForm para esta página.

Detalhando um pouco do atributo action  O valor para o atributo action da tag Struts <html:form /> é usado para selecionar ActionMapping, onde é assumido o nome suposto da página que processará o pedido, do qual você pode identificar o ActionForm apropriado e a extensão. Se a extensão mapeada em uso for “*.do” (padrão do Struts), o valor do atributo action deverá ser igual ao valor do atributo path correspondente para esse elemento, opcionalmente seguido pelo sufixo de extensão correto: <html:form action="NomeForm.do" focus="nome"> Ou: <html:form action="NomeForm" focus="nome">

As Tags Logic de Struts A biblioteca de tags Logic contém tags utilizadas para o gerenciamento condicional, resultando na saída de texto, loop sobre coleções de objetos ( geração repetitiva de saída de texto) e administração de fluxo da aplicação. Estas tags podem ser chamadas através da diretiva taglib existente em uma página JSP: <%@taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic"%> Como pode notar, a biblioteca Logic do Struts é chamada pela URI: http://jakarta.apache.org/struts/tags-logic E que contém o prefixo padrão logic.

Page 46: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

4646

A Tabela 3 a seguir demonstra as tags Logic do Struts: Tabela 3 - Tags Logic do Struts Nome da Tag Descrição

empty Avalia o conteúdo do corpo aninhado desta tag e se a variável pedida forum null ou uma string vazia.

equal Avalia se o conteúdo existente no corpo aninhado desta tag é uma variáveligual ao valor especificado.

forward Despacha o controle para a página especificada pela entradaActionForward.

greaterEqual Avalia o conteúdo no corpo desta tag no qual a variável pedida contém um valor maior que ou igual ao valor especificado.

greaterThan Avalie o conteúdo do corpo desta tag se a variável pedida for maior que ovalor especificado.

iterate Repita o conteúdo de corpo desta tag sobre uma coleção especificada.

lessEqual Avalia o conteúdo de corpo desta tag se a variável pedida for menor queou igual ao valor especificado.

lessThan Avalia o conteúdo de corpo desta tag se a variável pedida for menor que ovalor especificado.

match Avalia o conteúdo de corpo desta tag se o valor especificado for umasubstring apropriada para a variável pedida.

messagesNotPresent Gera o conteúdo do corpo desta tag se a mensagem especificada nãoestiver presente neste pedido.

messagesPresent Gera o conteúdo do corpo desta tag se a mensagem especificada estiverpresente neste pedido.

notEmpty Avalia o conteúdo do corpo desta tag se a variável pedida não for nullnem uma String vazia.

notEqual Avalia o conteúdo do corpo desta tag se a variável pedida não for igual ao valor especificado.

notMatch Avalia o conteúdo do corpo desta tag se o valor especificado não for umasubstring apropriada para a variável pedida.

notPresent Gera o conteúdo do corpo desta tag se o valor especificado não estiverpresente neste pedido.

present Gera o conteúdo do corpo desta tag se o valor especificado estiverpresente neste pedido.

redirect Renderiza um redirecionamento HTTP. Seu uso pode ser visto na página sucesso.jsp, visto na Listagem 6: <logic:present name="integrator" scope="request"> <h2> <bean:write name="integrator" property="nome" /> </h2> </logic:present>

Page 47: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

4747

AS Tags Bean  de Struts As tags que fazem parte da biblioteca de tags Bean são usadas para acessar JavaBeans, e outras propriedades associadas, como também definir novos beans que serão acessíveis para o resto da página, através de variáveis scripting e atributos de escopo de página. Estas tags possuem os mecanismos necessários para criar um novo bean, baseado nos valores de pedidos através de cookies, cabeçalhos e parâmetros que são fornecidos. Essas tags podem ser chamadas através da diretiva taglib existente em uma página JSP: <%@taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%> Como pode notar, a biblioteca Bean do Struts é chamada pela URI: http://jakarta.apache.org/struts/tags-bean E que contém o prefixo padrão bean. A Tabela 4 a seguir demonstra as tags Bean do Struts: Tabela 4 - As tags Bean do Struts

Nome da tag Descrição

cookie Define uma variável baseada no(s) valore(s) especificados no cookie pedido.

define Define uma variável baseada no(s) valore(s) especificados na propriedade bean.

header Define uma variável baseada no(s) valore(s) especificados no pedido header.

include Carrega a resposta para uma aplicação dinâmica pedida e a torna disponível como um bean.

message Renderiza uma mensagem string internacionalizada para a resposta.

page Expõe um item especificado do contexto da página como um bean.

parameter Define uma variável baseada no(s) valore(s) especificados no parâmetro pedido.

resource Carrega um recurso da aplicação web e a torna disponível como um bean.

size Define um bean contendo o número de elementos em um Collection ou Map.

struts Expõe para um Struts nomeado um objeto de configuração interno como um bean.

write Renderiza o valor de uma propriedade bean específica.

Você utilizou a tag Struts <bean:write /> para imprimir o nome transmitido pelo formulário na página sucesso.jsp:

Page 48: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

4848

<bean:write name="integrator" property="nome" />

Utilizando Struts para acessar banco de dados Para compreender um pouco mais sobre Struts, você vai criar um CRUD de exemplo, utilizando banco de dados e o padrão DAO. Crie um novo projeto utilizando o framework Struts. Se desejar, chame-o de UtilStrutsComDAO. Adicione a biblioteca JDBC do MySQL ao projeto.

Criando o JavaBean Autor Para o exemplo, será utilizado a manipulação da tabela autores no banco de dados. Para iniciar, crie uma classe chamada Autor, que será nosso JavaBean. Altere-a como na Listagem 7 a seguir. Listagem 7. O JavaBean Autor package br.com.integrator; import java.util.Date; public class Autor { private Integer id; private String nome; private String email; private Date nascimento; public Autor() { } public Autor(Integer id, String nome, String email, Date nascimento) { this.id = id; this.nome = nome; this.email = email; this.nascimento = nascimento; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Date getNascimento() { return nascimento; }

Page 49: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

4949

public void setNascimento(Date nascimento) { this.nascimento = nascimento; } }

A fábrica de conexão No pacote br.com.integrator.util, será criada a classe ConnectionFactory, que será sua fábrica de conexões. A Listagem 8 exibe a classe. Listagem 8. A classe ConnectionFactory package br.com.integrator.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class ConnectionFactory { public static Connection getConnection() throws Exception { try { Class.forName("com.mysql.jdbc.Driver"); return DriverManager.getConnection( "jdbc:mysql://localhost/livraria", "edson", "integrator"); } catch (Exception e) { throw new Exception(e.getMessage()); } } public static void closeConnection(Connection conn, Statement stmt, ResultSet rs) throws Exception { close(conn, stmt, rs); } public static void closeConnection(Connection conn, Statement stmt) throws Exception { close(conn, stmt, null); } public static void closeConnection(Connection conn) throws Exception { close(conn, null, null); } private static void close(Connection conn, Statement stmt, ResultSet rs) throws Exception { try { if (rs != null) rs.close(); if (stmt != null)stmt.close(); if (conn != null)conn.close(); } catch (Exception e) { throw new Exception(e.getMessage()); } } }

Criando o DAO Como agora possuímos a fábrica de conexões, que servirá o acesso ao banco de dados e nosso JavaBean, será criada a camada de manipulação ao banco de dados. No pacote br.com.integrator.dao, será criada a interface DAO e sua implementação AutorDAOImp. As Listagens 9 e 10 exibe DAO e AutorDAOImp respectivamente.

Page 50: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

5050

Listagem 9. A interface DAO package br.com.integrator.dao; import br.com.integrator.Autor; import java.util.List; public interface DAO { void atualizar(Autor autor) throws Exception; void excluir(Autor autor) throws Exception; Autor procurarAutor(Integer id) throws Exception; void salvar(Autor autor) throws Exception; List todosAutores() throws Exception; } Listagem 10. A classe implementada AutorDAOImp package br.com.integrator.dao; import br.com.integrator.Autor; import br.com.integrator.util.ConnectionFactory; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * A classe <B>AutorDAOImp</B> cria o CRUD necessário para * manipular a tabela <B>autores</B> e implementa <I>DAO</I> * @author Edson Gonçalves * @since 22-12-2007 * @version 1.0 */ public class AutorDAOImp implements DAO { private Connection conn; /** * Método construtor que se conecta ao banco de dados * @throws java.lang.Exception se não houver conexão */ public AutorDAOImp( ) throws Exception{ try { this.conn = ConnectionFactory.getConnection( ); } catch( Exception e ) { throw new Exception( "Erro: " + e.getMessage( ) ); } } /** * Método que insere dados na tabela Autores * @param autor - recebe o objeto Autor * @throws java.lang.Exception se não conseguir inserir */ @Override public void salvar(Autor autor) throws Exception{ PreparedStatement ps = null; Connection conn = null; if (autor == null) throw new

Page 51: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

5151

Exception("O valor passado não pode ser nulo"); try { String SQL = "INSERT INTO autores (nome, email, nascimento) "+ "values (?, ?, ?)"; conn = this.conn; ps = conn.prepareStatement(SQL); ps.setString(1, autor.getNome( )); ps.setString(2, autor.getEmail( )); ps.setDate(3, new java.sql.Date(autor.getNascimento( ).getTime())); ps.executeUpdate( ); } catch (SQLException sqle) { throw new Exception("Erro ao inserir dados " + sqle); } finally { ConnectionFactory.closeConnection(conn, ps); } } /** * Método que exclui uma linha na tabela aAutores * @param autor - recebe o objeto Autor * @throws se não for possível excluir o autor */ @Override public void excluir(Autor autor) throws Exception { PreparedStatement ps = null; Connection conn = null; if (autor == null) throw new Exception("O valor passado não pode ser nulo"); try { conn = this.conn; ps = conn.prepareStatement("delete from autores where id=?"); ps.setInt(1, autor.getId( )); ps.executeUpdate( ); } catch (SQLException sqle) { throw new Exception("Erro ao excluir dados:" + sqle); } finally { ConnectionFactory.closeConnection(conn, ps); } } /** * Método que atualiza os dados na tabela autores * @param autor - recebe o objeto Autor * @throws java.lang.Exception se não for possível atualizar */ public void atualizar(Autor autor) throws Exception { PreparedStatement ps = null; Connection conn = null; if (autor == null) throw new Exception("O valor passado não pode ser nulo"); try { String SQL = "UPDATE autores SET nome=?, " + " email=?, " + "nascimento=? " + "where id=?";

Page 52: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

5252

conn = this.conn; ps = conn.prepareStatement(SQL); ps.setString(1, autor.getNome( )); ps.setString(2, autor.getEmail( )); ps.setDate(3, new java.sql.Date(autor.getNascimento( ).getTime()) ); ps.setInt(4, autor.getId( )); ps.executeUpdate( ); } catch (SQLException sqle) { throw new Exception("Erro ao atualizar dados: " + sqle); } finally { ConnectionFactory.closeConnection(conn, ps); } } /** * Método que retorna todos os autores * @return objeto List * @throws java.lang.Exception se não for possível retornar o objeto List */ public List todosAutores() throws Exception{ PreparedStatement ps = null; Connection conn = null; ResultSet rs = null; try { conn = this.conn; ps = conn.prepareStatement("select * from autores"); rs = ps.executeQuery( ); List<Autor> list = new ArrayList<Autor>( ); while( rs.next( ) ) { Integer autorId = rs.getInt( 1 ); String nome = rs.getString( 2 ); String email = rs.getString( 3 ); Date nascimento = rs.getDate( 4 ); list.add( new Autor(autorId,nome,email,nascimento) ); } return list; } catch (SQLException sqle) { throw new Exception(sqle); } finally { ConnectionFactory.closeConnection(conn, ps, rs); } } /** * Método responsável por pesquisar um autor * @param id - recebe um Inteiro como parâmetro para pesquisar * pelo campo id * @return objeto Autor * @throws java.lang.Exception se não for possível retornar o objeto Autor */ public Autor procurarAutor(Integer id) throws Exception { PreparedStatement ps = null; Connection conn = null; ResultSet rs = null; try { conn = this.conn; ps = conn.prepareStatement("select * from autores where id=?"); ps.setInt(1, id); rs = ps.executeQuery( );

Page 53: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

5353

if( !rs.next( ) ) { throw new Exception( "Não foi encontrado nenhum registro com o ID: " + id ); } String nome = rs.getString( 2 ); String email = rs.getString( 3 ); Date nascimento = rs.getDate( 4 ); return new Autor(id, nome, email, nascimento) ; } catch (SQLException sqle) { throw new Exception(sqle); } finally { ConnectionFactory.closeConnection(conn, ps, rs); } } } O DAO criado é similar ao do livro, no Capítulo 4. Caso tenha alguma dúvida, recorra a ele para obter detalhes com explicações para sua maior compreensão.

Gerando as classes Struts Crie um novo arquivo. Selecione em Categories o item Struts e clique em Struts ActionForm Bean em File Types. Dê o nome de AutoresActionForm em Class Name e selecione em Package o pacote br.com.integrator.struts. Clique no botão Finish para confirmar.

Figura 16 – Criação do ActionForm AutoresActionForm Na Listagem 11 a seguir há a classe para que você a altere.

Page 54: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

5454

Listagem 11. A classe AutoresActionForm package br.com.integrator.struts; import java.util.ArrayList; import javax.servlet.http.HttpServletRequest; import org.apache.struts.action.ActionMapping; public class AutoresActionForm extends org.apache.struts.action.ActionForm { private ArrayList autor = new ArrayList(); public ArrayList getAutor() { return autor; } public void setAutor(ArrayList autor) { this.autor = autor; } public AutoresActionForm() { super(); } public void reset(ActionMapping mapping, HttpServletRequest request) { autor = new ArrayList(); } } Neste ActionForm foi criado um java.util.ArrayList que trará os dados encontrados na tabela para serem acessíveis pela página na camada apresentação (View), que exibirá uma tabela de dados. O próximo passo é desenvolver a action que se responsabilizará pela comunicação com os dados. Crie um novo arquivo do tipo Struts Action na categoria Struts. Chame de AutoresAction e coloque no pacote br.com.integrator.struts. No campo Action Path digite /AutoresActionForm. Clique no botão Next para prosseguir.

Figura 17 – Geração do Struts Action AutoresAction

Page 55: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

5555

Na terceira e última etapa do assistente, em Input Resource selecione o arquivo welcomeStruts.jsp clicando no botão Browse. Marque a opção Request e clique no botão Finish para completar.

Figura 18 – Configurando o ActionForm Altere seu código como o mostrado na Listagem 12 a seguir. Listagem 12. A classe AutoresAction package br.com.integrator.struts; import br.com.integrator.dao.AutorDAOImp; import br.com.integrator.dao.DAO; import java.util.ArrayList; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionForward; public class AutoresAction extends Action { /* forward name="success" path="" */ private final static String SUCCESS = "success"; public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { AutoresActionForm autoresForm = (AutoresActionForm) form; DAO dao = new AutorDAOImp(); autoresForm.setAutor((ArrayList) dao.todosAutores()); return mapping.findForward(SUCCESS); } }

Page 56: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

5656

Perceba que você irá chamar AutoresActionForm e o DAO para trazer os autores. Através do método setAutor(), criado na classe AutoresActionForm, você irá recuperar todos os dados existentes na tabela do MySQL autores, encontrada no banco de dados livraria, através do método gerado na classe AutorDAOImp, chamado de todosAutores(). Como o método todosAutores() retorna um java.util.List, uma coerção para java.util.ArrayList é necessária, uma vez que o método setAutor() utiliza este objeto como tipo.

Configurando o arquivo struts­config.xml No arquivo struts-config.xml, vá por entre os elementos <action /> e clique com o direito do mouse. Selecione no menu de contexto o item Add Forward em Struts. Na caixa de diálogo, digite success em Forward Name e selecione em Resource File welcomeStruts.jsp. Clique no botão Add para confirmar.

Figura 19 – Geração do elemento <forward/> em struts-config.xml Seu arquivo struts-config.xml deverá estar com o trecho semelhante ao mostrado na Listagem 13 seguir: Listagem 13. O resultado final configurado em struts-config.xml <!--... omitido por não haver alterações --> <action-mappings> <action input="/welcomeStruts.jsp" name="AutoresActionForm" path="/AutoresActionForm" scope="request" type="br.com.integrator.struts.AutoresAction"> <forward name="success" path="/welcomeStruts.jsp"/> </action> <action path="/Welcome" forward="/welcomeStruts.jsp"/> </action-mappings> <!--... omitido por não haver alterações -->

Page 57: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

5757

Exibindo os dados da tabela A página welcomeStruts.jsp será utilizada para a exibição dos autores cadastrados em formato tabular, encontrado na tabela autores do banco de dados livraria. A página welcomeStruts.jsp é mostrada na íntegra na Listagem 14 a seguir. Listagem 14. A página welcomeStruts.jsp <%@page contentType="text/html"%> <%@page pageEncoding="ISO-8859-1"%> <%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> <%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %> <%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> <html:html> <head> <title>Autores Cadastrados</title> </head> <body> <table border="1"> <thead> <tr> <td>ID</td> <td>Nome</td> <td>E-mail</td> <td>Nascimento</td> </tr> </thead> <tbody> <logic:iterate name="AutoresActionForm" property="autor" id="autor"> <tr> <td><bean:write name="autor" property="id" /></td> <td><bean:write name="autor" property="nome" /></td> <td><bean:write name="autor" property="email" /></td> <td> <bean:write name="autor" property="nascimento" format="dd/MM/yyyy"/> </td> </tr> </logic:iterate> <logic:notPresent name="autor"> <tr> <td colspan="3">Nenhum autor encontrado.</td> </tr> </logic:notPresent> </tbody> </table> </body> </html:html> A criação desta página é bem simples, o Struts irá gerar uma tabela através de um loop, utilizando a tag <logic:iterate />, que percorrerá os dados encontrados na propriedade autor, do ArrayList existente na classe AutoresActionForm. Depois transmitirá pelo id os resultados, que serão, um a um, impressos pela tag <bean:write />, através do atributo property. Observe que para a data de nascimento do autor, existe o atributo format que define o padrão a ser usado neste caso.Se não houver dados, a tag <logic:notPresent /> apresentará uma mensagem ao usuário. Por fim, para chamar esta página, altere a página index.jsp. O link desta página deverá chamar AutoresActionForm, para que todo o processo seja iniciado. A Listagem 15 exibe as alterações propostas para a página.

Page 58: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

5858

Listagem 15. A página index.jsp <%@page contentType="text/html"%> <%@page pageEncoding="ISO-8859-1"%> <%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Pagina Inicial</title> </head> <body> <h1>Autores Cadastrados</h1> <br/> <html:link action="AutoresActionForm">Mostrar Autores</html:link> </body> </html> O link é criado pela tag Struts <html:link />, chamando pelo atributo action a página mapeada por AutoresActionForm.

Figura 20 – Resultado da página que será exibida

Adicionando, Editando e Excluindo autores Crie um novo arquivo. Selecione em Categories o item Struts e clique em Struts ActionForm Bean em File Types. Dê o nome de EditarAutoresForm em Class Name e selecione em Package o pacote br.com.integrator.struts. Clique no botão Finish para confirmar. Listagem 16. A classe EditarAutoresForm package br.com.integrator.struts; public class EditarAutoresForm extends org.apache.struts.action.ActionForm { private Integer id; private String nome; private String email; private String nascimento; public Integer getId() { return id; } public void setId(Integer id) { this.id = id;

Page 59: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

5959

} public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getNascimento() { return nascimento; } public void setNascimento(String nascimento) { this.nascimento = nascimento; } } Neste ActionForm foi criado os campos que irão compor os formulários de inserir e atualizar. Crie um novo arquivo do tipo Struts Action na categoria Struts. Chame de EditarAutoresAction e coloque no pacote br.com.integrator.struts. No campo Action Path digite /Operacao. Clique no botão Next para prosseguir. Na terceira e última etapa do assistente, em Input Resource selecione o arquivo welcomeStruts.jsp clicando no botão Browse. Marque a opção Request e clique no botão Finish para completar. Altere seu código como o mostrado na Listagem 17 a seguir. Listagem 17. A classe EditarAutoresAction package br.com.integrator.struts; import br.com.integrator.Autor; import br.com.integrator.dao.AutorDAOImp; import br.com.integrator.dao.DAO; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.actions.DispatchAction; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionForward; public class EditarAutoresAction extends DispatchAction { public ActionForward editAutor( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { EditarAutoresForm editarAutoresForm = (EditarAutoresForm) form; Integer id = Integer.parseInt(request.getParameter("id")); DAO dao = new AutorDAOImp(); Autor autor = dao.procurarAutor(id); editarAutoresForm.setId(autor.getId());

Page 60: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

6060

editarAutoresForm.setNome(autor.getNome()); editarAutoresForm.setEmail(autor.getEmail()); editarAutoresForm.setNascimento(dateToString(autor.getNascimento())); return mapping.findForward("showEdit"); } public ActionForward deleteAutor( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { EditarAutoresForm editarAutoresForm = (EditarAutoresForm) form; Integer id = Integer.parseInt(request.getParameter("id")); DAO dao = new AutorDAOImp(); Autor autor = new Autor(); autor.setId(id); dao.excluir(autor); return mapping.findForward("success"); } public ActionForward addAutor( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { EditarAutoresForm editarAutoresForm = (EditarAutoresForm) form; return mapping.findForward("showAdd"); } public ActionForward saveAutor( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { EditarAutoresForm editarAutoresForm = (EditarAutoresForm) form; DAO dao = new AutorDAOImp(); Autor autor = new Autor(); autor.setId(editarAutoresForm.getId()); autor.setNome(editarAutoresForm.getNome()); autor.setEmail(editarAutoresForm.getEmail()); autor.setNascimento(strToDate(editarAutoresForm.getNascimento())); if(autor.getId()==null) dao.salvar(autor); else dao.atualizar(autor); return mapping.findForward("success"); } private Date strToDate(String data) throws Exception { if (data == null) return null; Date dataF = null; try { DateFormat dateFormat =

Page 61: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

6161

new SimpleDateFormat("dd/MM/yyyy"); long timestamp = dateFormat.parse(data).getTime( ); dataF = new Date(timestamp); } catch (Exception e) { } return dataF; } public static String dateToString(Date data) throws Exception { if (data == null || data.equals("")) return null; String dataF = null; try { DateFormat df = new SimpleDateFormat("dd/MM/yyyy"); dataF = df.format(data); } catch (Exception e) { } return dataF; } } Perceba que você irá chamar EditarAutoresActionForm e o DAO para trabalhar com os autores. Cada um dos métodos cria uma ação para atualizar, excluir ou inserir novos autores. Para editar um autor, por exemplo, chamamos o método editAutor(). Cada campo do formulário é alimentado com os dados encontrados na tabela, pesquisado através do parâmetro id transmitido com o número do autor que será atualizado. Para alimentar os campos, no DAO, chamamos o método procurarAutor(). A string retornada para redirecionar a página é showEdit. public ActionForward editAutor( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { EditarAutoresForm editarAutoresForm = (EditarAutoresForm) form; Integer id = Integer.parseInt(request.getParameter("id")); DAO dao = new AutorDAOImp(); Autor autor = dao.procurarAutor(id); editarAutoresForm.setId(autor.getId()); editarAutoresForm.setNome(autor.getNome()); editarAutoresForm.setEmail(autor.getEmail()); editarAutoresForm.setNascimento(dateToString(autor.getNascimento())); return mapping.findForward("showEdit"); } O método de exclusão segue a mesma lógica, capturando o id do autor e removendo-o através do método excluir() de DAO. O resultado desta ação é uma string success. public ActionForward deleteAutor( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { EditarAutoresForm editarAutoresForm = (EditarAutoresForm) form;

Page 62: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

6262

Integer id = Integer.parseInt(request.getParameter("id")); DAO dao = new AutorDAOImp(); Autor autor = new Autor(); autor.setId(id); dao.excluir(autor); return mapping.findForward("success"); } Para adicionar um novo autor, o método addAutor() é chamado, onde retorna a string mapeada showAdd para redirecionar o usuário. public ActionForward addAutor( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { EditarAutoresForm editarAutoresForm = (EditarAutoresForm) form; return mapping.findForward("showAdd"); } Na hora de salvar o autor, seja após uma atualização ou inserção de dados, será chamado o método saveAutor(). Neste caso, os dados recuperados do formulário são transmitidos para o objeto Autor. Para salvar, se o id de autor for null, significa que é um novo cadastro, chamando o método DAO salvar(). Do contrário, é uma atualização, chamando atualizar(). public ActionForward saveAutor( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { EditarAutoresForm editarAutoresForm = (EditarAutoresForm) form; DAO dao = new AutorDAOImp(); Autor autor = new Autor(); autor.setId(editarAutoresForm.getId()); autor.setNome(editarAutoresForm.getNome()); autor.setEmail(editarAutoresForm.getEmail()); autor.setNascimento(strToDate(editarAutoresForm.getNascimento())); if(autor.getId()==null) dao.salvar(autor); else dao.atualizar(autor); return mapping.findForward("success"); }

Page 63: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

6363

Configurando o arquivo struts­config.xml No arquivo struts-config.xml, vá por entre os elementos <action /> de editarAutoresForm e altere como na Listagem 18. Listagem 18. Alterações no arquivo struts-config.xml <!-- ...omitido por não haver alterações --> <action attribute="editarAutoresForm" name="editarAutoresForm" parameter="acao" path="/Operacao" scope="request" type="br.com.integrator.struts.EditarAutoresAction"> <forward name="showEdit" path="/jsp/editAutor.jsp" /> <forward name="showAdd" path="/jsp/addAutor.jsp" /> <forward name="success" path="/AutoresActionForm.do" redirect="true" /> </action> <!-- ...omitido por não haver alterações --> Observe que temos os casos retornados pela classe EditarAutoresActionForm definindo suas respectivas páginas.

As páginas para editar e inserir dados Para editar os dados, haverá uma chamada a página editAutor.jsp. Para adicionar os dados, uma página chamada addAutor.jsp. Estas páginas serão criadas dentro do diretório jsp. Veja na Figura 21 as duas páginas JSP que serão criadas no seu projeto.

Page 64: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

6464

Figura 21 - Os arquivos encontrados dentro do diretório jsp Crie a página addAutor.jsp, em jsp, e altere como na Listagem 19 exibida a seguir: Listagem 19. Alterações no arquivo struts-config.xml <%@page contentType="text/html"%> <%@page pageEncoding="ISO-8859-1"%> <%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Adicionar Autor</title> </head> <body> <%-- cria um form html --%> <html:form action="Operacao"> <%-- cria a tabela com os campos --%> <table border="1"> <tbody> <tr> <td>Nome:</td> <td><html:text property="nome" /></td> </tr> <tr> <td>E-mail:</td> <td><html:text property="email" /></td> </tr> <tr> <td>Nascimento:</td> <td><html:text property="nascimento" /></td> </tr> <tr> <td colspan="2"> <html:submit>Cadastrar</html:submit> </td> </tr>

Page 65: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

6565

</tbody> </table> <%-- o parametro necessario para chamar o metodo saveAutor() --%> <html:hidden property="acao" value="saveAutor" /> </html:form> </body> </html>

Figura 22 – A página de inserção de autores em ação A página addAutor.jsp utiliza a tag Struts <html:text /> para criar os campos <input /> do HTML do tipo text. Cada campo é amarrado a classe EditarAutoresForm através do atributo property. Para criar o botão de envio, foi utilizada a tag Struts <html:submit/>. Observe que no fim da página, há um campo oculto do Struts, <html:hidden />, ao qual possui dois atributos:

• property – o parâmetro a ser transmitido • value – o nome do método que sera chamado

Crie a página editAutor.jsp, em jsp, e altere como na Listagem 20 exibida a seguir: Listagem 20. Alterações no arquivo struts-config.xml <%@page contentType="text/html"%> <%@page pageEncoding="ISO-8859-1"%> <%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Editar Autor</title> </head> <body> <%-- cria o formulario html --%> <html:form action="Operacao"> <%-- imprime os dados encontrados do autor nos campos --%> <table border="1"> <tbody> <tr> <td>Nome:</td> <td><html:text property="nome" /></td> </tr> <tr> <td>E-mail:</td> <td><html:text property="email" /></td> </tr> <tr> <td>Nascimento:</td> <td><html:text property="nascimento" /></td> </tr>

Page 66: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

6666

<tr> <td colspan="2"> <html:submit>Atualizar</html:submit> </td> </tr> </tbody> </table> <%-- cria um campo oculto contendo o ID do autor --%> <html:hidden property="id" /> <%-- envia para o metodo saveAutor() --%> <html:hidden property="acao" value="saveAutor" /> </html:form> </body> </html> A página para editar autores é similar a de cadastro, com a diferença de ter um campo oculto que receberá o id do autor que será atualizado.

Figura 23 – A página de edição de autores em ação

Alterando a página que exibe todos os autores Para finalizar, iremos alterar a página welcomeStruts.jsp para executarmos as ações de inserir, atualizar e excluir o autor. A Listagem 21 mostra na íntegra as alterações criadas na página. Listagem 21. A página welcomeStruts.jsp <%@page contentType="text/html"%> <%@page pageEncoding="ISO-8859-1"%> <%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %> <%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %> <%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %> <html:html> <head> <title>Autores Cadastrados</title> </head> <body> <table border="1"> <thead> <tr> <td>ID</td> <td>Nome</td> <td>E-mail</td> <td>Nascimento</td> <td colspan="2" align="center">Ações</td> </tr> </thead> <tbody> <logic:iterate name="AutoresActionForm" property="autor" id="autor"> <tr> <td><bean:write name="autor" property="id" /></td> <td><bean:write name="autor" property="nome" /></td> <td><bean:write name="autor" property="email" /></td>

Page 67: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

6767

<td> <bean:write name="autor" property="nascimento" format="dd/MM/yyyy"/> </td> <td> <html:link action="Operacao.do?acao=editAutor" paramName="autor" paramProperty="id" paramId="id">Editar</html:link> </td> <td> <html:link action="Operacao.do?acao=deleteAutor" paramName="autor" paramProperty="id" paramId="id">Excluir</html:link> </td> </tr> </logic:iterate> <logic:notPresent name="autor"> <tr> <td colspan="3">Nenhum autor encontrado.</td> </tr> </logic:notPresent> </tbody> </table> <html:link action="Operacao.do?acao=addAutor">Adicionar novo Autor</html:link> </body> </html:html>

Figura 24 – A página que exibe todos os autores com as alterações

Page 68: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

6868

Capítulo Extra 4 

Desenvolvendo Relatórios com NetBeans IDE Este capítulo extra o instruirá no desenvolvimento de relatórios JasperReports básicos utilizando o novo plugin iReport for NetBeans, que o NetBeans IDE 6 agora possui. No momento em que este livro é escrito, sua versão ainda não é final.

O JasperReports O JasperReports nasceu em 2001, criado por Teodor Danciu, quando este teve a tarefa de avaliar ferramentas de relatórios para um projeto em que estava trabalhando. As soluções existentes eram muito caras para o orçamento do projeto e, em uma situação comum no mundo do desenvolvimento, ele decidiu escrever sua própria ferramenta de relatórios, que ao liberá-la para a comunidade, ficou imensamente popular em pouco tempo. JasperReports é uma biblioteca escrita em Java, de código fonte open source, projetada para ajudar o desenvolvedor com a tarefa de criar relatórios para aplicações, tanto Desktop como Web, fornecendo uma API que facilita sua geração. Embora seja simples, ainda exige que o desenvolvedor conheça seu formato XML utilizado para criar os relatórios, o que torna dispendioso o tempo de um iniciante.

O iReport para o NetBeans O iReport é um programa Open Source, criado em 2002 por Giulio Toffoli, capaz de criar visualmente os mais complexos relatórios para aplicações Java no formato da biblioteca JasperReports. Sua versão atual é escrito em 100% Java, e seus códigos fontes são distribuídos gratuitamente de acordo com a GNU (General Public License). Em 2005, com a popularidade do iReport, a JasperSoft (mantenedora do JasperReports) tornou esta ferramenta oficial na construção de relatórios para o JasperReports. Recentemente seu criador começou a portar a ferramenta para a plataforma do NetBeans, criando duas versões: um plugin que pode ser instalado na IDE ou standalone. Através de uma interface gráfica intuitiva, o desenvolvedor é capaz de criar qualquer tipo de relatório de forma simples e rápida. Mesmo sabendo que o iReport desenvolve um formato XML usado pelo JasperReports, o que não é difícil de manipular, há uma vantagem em usar esta ferramenta. Se o desenvolvedor é um usuário iniciante no formato XML do JasperReports, o iReport supre suas necessidades evitando que seja necessário fazer modificações no código fonte. Caso seja experiente neste formato, o iReport minimiza o tempo na criação dos mais complexos relatórios.

Desenvolvendo relatórios com NetBeans O iReport é um bem-sucedido programa Open Source, capaz de criar visualmente os mais complexos relatórios para aplicações Java no formato da biblioteca JasperReports. Atualmente, além de ser um programa gráfico independente, há também uma versão disponível que se integra ao NetBeans IDE 6.0. Através de uma interface gráfica e intuitiva, o desenvolvedor é capaz de criar qualquer tipo de relatório de forma simples e rápida. O iReport para NetBeans desenvolve um formato XML usado pelo JasperReports, evitando naturalmente a edição no código.

Page 69: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

6969

Neste capítulo você aprenderá onde obter, como instalar, criar seu relatório e integrá-lo a suas aplicações Web conhecendo algumas características do iReport.

Obtendo e instalando o iReport para NetBeans Para obter o iReport para NetBeans, primeiramente você precisará baixar o plugin. Para isso, o endereço oficial para baixá-lo é: http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=4424. Clique no botão Download. Você obterá o arquivo .nbm para instalação. Atenção: No momento em que este livro está sendo escrito, este plugin ainda se encontra em versão BETA, sem algumas funcionalidades encontradas no iReport. Vá ao menu Tools e clique no item Plugins. Na caixa de diálogo Plugins, vá à guia Downloaded e clique no botão Add Plugins, selecionando, através da caixa de diálogo o arquivo de extensão .nbm pertencente ao iReport para NetBeans. Ao fazê-lo, clique no botão Install.

Figura 1 – Adição do plugin ireport-designer Ao clicar no botão Install, a caixa de diálogo NetBeans IDE Installer surgirá. Clique no botão Next para prosseguir com a instalação.

Page 70: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

7070

Figura 2 – Início da instalação do plugin ireport-designer Na etapa seguinte, você deverá aceitar os termos de licença. Clique na opção I accept the terms in all of the license agreements e clique no botão Install. A caixa de diálogo Validation Waring surgirá, dizendo que o plugin a ser instalado não foi assinado e que é potencialmente inseguro. Clique em Continue.

Figura 3 – Validação do plugin Ao terminar a instalação, clique no botão Finish. Retornando a caixa de diálogo Plugins, observe, na guia Installed, que o plugin ireport-designer está instalado. Clique no botão Close para fechar a janela.

Page 71: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

7171

Figura 4 – Plugin instalado

Criando um relatório para trabalhar com Servlets Crie um projeto Web chamado de RelatoriosComServlet. Em Web Pages crie um diretório chamado relatorios. Clique com o direito neste diretório e no menu de contexto selecione New e clique em Other. Na caixa de diálogo New File selecione JrxmlTemplate.jrxml, em Reports. Em alternativa, caso esteja aparecendo a opção JrxmlTemplate.jrxml no menu New, selecione-a. Na segunda etapa, digite o nome do seu relatório. Se preferir seguir o livro, chame-o de relatório e conclua o assistente.

Figura 5 – Criando um documento JasperReports

Page 72: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

7272

A estrutura e propriedades de um relatório JasperReports  Ao finalizar o assistente, o Designer do iReport para NetBeans surgirá. Além do Design, você possui a possibilidade de visualizar em formato XML e fazer um Preview. Um relatório no JasperReports possui diversas seções, separadas por linhas horizontais ao qual são chamadas de Bands (bandas). O comportamento de cada Band depende da funcionalidade para a qual está preparada. Quando o relatório junta aos dados para fazer a impressão, estas seções são impressas na tela de diferentes maneiras com diferentes tempos. Por exemplo, o cabeçalho da página (pageHeader) é repetido em todas as páginas, uma vez em cada página, enquanto que os detalhes onde serão exibidos os dados (detail) é gerado em uma seqüência elaborada de acordo com os dados existentes (query ou datasource), repetindo-se uma vez para cada registro, incorporando-se ao desenho do relatório. As bands de um relatório JasperReports é dividido em dez seções pré-definidas para que novos grupos possam ser adicionados. Embora as bands já estejam adicionadas e com espaçamentos pré-definidos inicialmente, você pode com o cursor, entre cada uma delas, nas linhas horizontais que as separam, e movê-las. Ao arrastar, você percebe que a altura de cada band se expande, empurrando as demais, após a alterada, para baixo ou vice-versa. Embora o desenvolvedor possa alterar a sua altura, em casos como a band detail, sua alteração implica na visibilidade e espaçamento dos elementos impressos na geração do relatório. Porém, nem todas as bands são organizadas dinamicamente pelo conteúdo, como é o caso de Column Footer, Page Footer e Last Page Footer.

Figura 6 – Estrutura do relatório JasperReports

Page 73: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

7373

Na janela Outline Window, você encontra os parâmetros (Parameters), campos da tabela da sua query (Fields), variáveis pré-definidas e criadas (Variables) e as bands do relatório. Por padrão, algumas bands estão desativadas ou com sua altura no valor zero, o que a torna invisível no design (como a band background).

Figura 7 – A janela Outline e os componentes do relatório Na janela Palette você encontra os elementos de um relatório.

Figura 8 – A janela Palette e os ReportElements Seguindo a imagem da Figura 8 você tem as seguintes ferramentas:

• Chart – Gera um gráfico através de valores determinados transmitidos. Mais adiante haverá um capítulo exclusivamente para gráficos.

• Image – Utilizado para exibir imagens em seu relatório. Podem ser imagens dinâmicas (preenchidas por um banco de dados, por exemplo) ou estáticas.

• Rectangle – Usado para desenhar retângulos ao redor de outros elementos, criando destaques como uma formatação de parágrafo de um programa de edição de textos, este elemento pode também conter retângulos com cantos arredondados.

Page 74: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

7474

• Text Field – Utilizado para criar os campos dinâmicos dos relatórios. É neste elemento que você se conecta a um determinado campo do banco de dados para exibir suas informações, por exemplo.

• Ellipse – Desenha elipses no relatório. • Line – Em um relatório JasperReports uma linha é definida por um elemento retangular

com uma linha diagonal. A linha pode ser desenhada em uma reta perfeita, na horizontal, vertical ou em ângulo se pressionada a tecla <Shift> antes de arrastar. A linha segue o grid.

• Static Text – Utilizado para criar rótulos de relatórios. Na parte inferior, da janela Palette se encontra as Properties. Quando um elemento é selecionado aparece nesta janela suas propriedades para serem alteradas.

Figura 9 – A janela Properties do relatório Nas propriedades do relatório, você possui o grupo Page size. Neste grupo você pode definir a largura da página (Page width) e a altura da página (Page height), bem como a Orientação (Orientation). Em Orientation, temos Portrait (Retrato) ou Landscape (Paisagem). Embora as dimensões sejam as mais importantes para a construção de um relatório, a unidade de medidas usada pelo iReport e JasperReports é em pixels (com uma resolução de 75 dpi). Para que você possa se orientar em um arquivo JRXML do JasperReports, a seguir a Tabela 1 mostra o padrão da página e seu valor em pixels.

Page 75: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

7575

Tabela 1 – Dimensões em pixels das páginas padronizadas Padrão da página Dimensão em Pixels LETTER 612 x 792 NOTE 540 x 720 LEGAL 612 x 1008 A0 2380 x 3368 A1 1684 x 2380 A2 1190 x 1684 A3 842 x 1190 A4 595 x 842 A5 421 x 595 A6 297 x 421 A7 210 x 297 A8 148 x 210 A9 105 x 148 A10 74 x 105 B0 2836 x 4008 B1 2004 x 2836 B2 1418 x 2004 B3 1002 x 1418 B4 709 x 1002 B5 501 x 709 ARCH_E 2592 x 3456 ARCH_D 1728 x 2592 ARCH_C 1296 x 1728 ARCH_B 864 x 1296 ARCH_A 648 x 864 FLSA 612 x 936 FLSE 612 x 936 HALFLETTER 396 x 612 11x17 792 x 1224 LEDGER 1224 x 792 No grupo Columns você pode definir quantas colunas seu relatório possuirá em uma página, no item Columns. Column Width automaticamente se altera quando você adiciona mais de uma coluna, dividindo sem o valor em partes iguais. Column Spacing determina o espaçamento entre colunas, que também influi em Column Width automaticamente. No grupo “More...” é possível especificar instruções para a impressão do relatório. Nele se encontram:

• Scriptlet Class - Onde você define um scriptlet, que nada mais é que uma classe Java cujos métodos são executados conforme são especificados os eventos durante a criação do relatório, como o início de uma nova página ou o fim de um grupo.

• Resource Bundle - É o nome do pacote de recursos usado para internacionalizar um relatório. É o Resource Bundle do Java, onde você define em um arquivo os textos traduzidos como rótulos. Cada linguagem corresponde a um arquivo específico.

• When Resource Missing Type – Se um pacote de recurso (Resource Bundle) não está disponível, você escolhe uma das opções na caixa de combinação. Representa o atributo whenResourceMissingType no JasperReports. Neste caso, você tem as seguintes opções:

Page 76: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

7676

1. Type Null (Nulo) – Imprime a string “Null”. Esta é a opção padrão. 2. Type Empty (Vazio) – Não imprime nada. Recebe como valor Empty no atributo

whenResourceMissingType de JasperReports. 3. Type the Key (Chave) – Imprime o nome chave que falta. Recebe como valor Key no

atributo whenResourceMissingType de JasperReports. 4. Rise an Error (Erro) – Lança uma exceção parando o processo. Recebe como valor

Error no atributo whenResourceMissingType de JasperReports.

• Query Text – Determina a query criada para o relatório. • Query Language – Determina a linguagem utilizada para a instrução. Pode ser: SQL,

HQL(Hibernate Query Language), XPath, EJBQL, MDX e XMLA-MDX. • Properties – Determina as propriedades para o objeto selecionado. • Title on a new page - Quando ativa, especifica se a banda title será impressa e em seguida

criada uma nova página, gerando uma “quebra de página”. • Summary on a new page - Esta opção é similar a anterior (Title on a new page), mas com

a diferença de ser a banda summary que será impressa como a última página. • Floating column footer - As bandas columnFooter são impressas por padrão no fim das

páginas. Se na impressão do relatório não houver dados suficientes para preencher uma página, um espaço em branco aparecerá entre a coluna e o rodapé da coluna (columnFooter). Se você quer que o texto encontrado na banda columnFooter seja impresso logo após a impressão da coluna, marque a opção Floating column footer. Esta opção permite forçar a impressão da banda columnFooter imediatamente após a última interação da banda detail e não do término de todas as colunas. Esta opção é geralmente usada quando você quer criar tabelas usando os elementos de relatórios.

• Ignore pagination - Ignora a paginação ao preencher o relatório, impossibilitando a visualização das demais páginas caso haja mais que uma. Quando ativa, esta opção implica até mesmo na visualização correta dos dados caso haja mais de uma coluna.

• Print Order - A ordem de impressão (Print Order) determina como os dados impressos na página serão organizados em mais de uma coluna. O padrão para a ordem de impressão é Vertical. Com a ordem Vertical, primeiro os dados são impressos um embaixo do outro, passando para uma nova coluna somente quando a coluna está totalmente preenchida no final da página. Na ordem Horizontal os dados são preenchidos em linha. Os dados passam por todas as colunas, adicionando uma nova linha somente quando a última coluna da página foi preenchida naquela determinada linha.

• When no data - Quando o número de dados para a impressão é vazio (query SQL sem dados, por exemplo), o relatório pode ter comportamentos diferentes para apresentar a página ao usuário. Neste caso existem quatro opções, listadas a seguir:

1. Type No Pages (Sem Páginas)– O padrão. O resultado final é um buffer vazio. 2. Type a Blank Page (Páginas em branco) – Exibe uma página em branco caso não haja

dados. 3. Type All Sections, No Detail (Todas as seções, nenhum detalhe) – Mostra todas as

seções existentes no relatório, menos os detalhes da banda detail. 4. Type “No Data” section – Seção sem dados. Utiliza a band noData, ou seja, você

adiciona um conteúdo estático (ou dinâmico sem usar o banco de dados) neste local. Caso não haja dados em uma determinada pesquisa ou sem conexão com o banco de dados, esta seção será exibida.

• Language – Determina a linguagem a ser utilizada no relatório. Neste caso, somente as duas linguagens oficiais do JVM são possíveis, por enquanto: Java ou Groovy.

Page 77: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

7777

• Format Factory Class - Recebe uma string com o nome da classe de formatos, habilitando o uso de datas personalizadas e formatos de números. Representa o atributo formatFactoryClass de JasperReports e implementa a interface net.sf.jasperreports.engine.

Exibindo o Grid Você pode exibir o Grid para desenhar o relatório, vá ao menu Designer e clique em Show Grid. Também é possível alinhar os elementos dentro do relatório se selecionar a opção Snap To Grid.

Figura 10 – Exibindo o Grid no Design

Adicionando uma conexão a um relatório em branco Para a construção deste relatório, vamos utilizar o banco de dados livraria. Vá ao menu Data e clique em Connections/Data Sources, ou na barra de ferramentas Designer.

Figura 11 – Connections / Datasources no menu Data e ferramentas Designer Na caixa de diálogo Connections / Datasources, clique no botão New. Em Datasource selecione o item NetBeans Database JDBC connection e clique no botão Next.

Page 78: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

7878

Figura 12 – Seleção do datasource NetBeans Database JDBC connection Na segunda etapa, selecione em Connection a conexão livraria usada neste livro e digite livraria em Name. Clique no botão Test. Se a caixa de diálogo “Connection test successful!” surgir, confirme e clique no botão Save.

Figura 13 – Configurando a conexão livraria

Page 79: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

7979

Para uma modificação da conexão, na caixa de diálogo Connections / Datasources temos o botão Modify. Basta selecionar a linha da sua conexão que deseja alterar e clicar neste botão. A caixa de diálogo de propriedades da conexão reabre. Basta alterar e salvar (Save). Em mais de uma conexão, você tem o botão Set as default. Basta selecionar a conexão que deseja tornar padrão (Default) e clicar neste botão. Observe que na caixa de diálogo a coluna Default apresenta a conexão padrão com uma caixa de checagem ativa. Caso você precise levar as configurações da sua conexão para outra máquina, ou quer guardá-la para uma futura reutilização, clique no botão Export. A caixa de diálogo para salvar a conexão aparecerá. Basta selecionar o local e dar o nome. Caso tenha mais de uma conexão, todas serão exportadas. Se precisar importar uma conexão do próprio iReport, basta clicar no botão Import. Depois de configurado, basta fechar a caixa de diálogo.

Figura 14 – Conexão criada e disponível

Criando a query do relatório Para criar a query do relatório, vá ao menu File e clique no item Report query. Alternativamente você pode ir ao ícone Report query, acima do design do relatório.

Figura 15 – Abrindo o Report query Ao abrir a caixa de diálogo Report Query, clique no botão Query designer. Outra caixa de diálogo surgirá, chamada de SQL Query Designer, mas desta vez para a criação da instrução SQL visual. Observe que há três quadros na janela. O primeiro, à esquerda, define a exibição da query de forma visual, separando os elementos padronizados de uma seleção de dados (SELECT, FROM, WHERE e etc.). A cada coluna de sua tabela selecionada, automaticamente a query adicionará na parte superior, em SELECT, o campo e um alias. Em FROM surgirá a, ou, as tabelas que estão relacionadas para tal seleção.

Page 80: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

8080

Você vai selecionar, através do segundo quadro a esquerda, a tabela autores, dando um duplo clique sobre seu respectivo nome. Esta seleção pode ser através do arrastar para o quadro da direita também, caso ache mais prático. Existem duas formas de você selecionar todos os campos de uma tabela, no Query designer. A primeira é ir até a tabela (no caso autores) e clicar no menu de mesmo nome, selecionando a opção select all. A segunda forma é clicando com o direito do mouse e selecionando a opção add expression, no quadro da esquerda, em SELECT.

Figura 16 – Adicionando uma expressão Neste caso, você digita o que deseja fazer, na caixa de diálogo expression.edit. Para o caso, digite “*” e confirme. Ao final, você possuirá uma configuração da sua query SELECT similar ao mostrado na Figura 17 a seguir:

Figura 17 – Query desenhada na caixa de diálogo SQL Query Designer

Page 81: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

8181

Se você clicar em SQL, a guia abaixo, ao lado de Builder (a atual), você verá a query construída. Confirme no botão OK. Retornando a caixa de diálogo Report query, você ainda pode fazer alterações na query criada. Na parte superior da janela, existe o botão Save query, caso deseje armazenar a consulta construída para uso posterior em outro relatório. Se esse for o caso, o carregamento de uma consulta armazenada pode ser feito através do botão Load query. Como a opção Automatically Retrieve Fields está selecionada, na parte inferior aparece cada campo selecionado, em uma tabela, com seus respectivos nomes e o tipo de dados em Java de cada um. É importante manter selecionada esta opção, uma vez que na digitação ou alteração de uma query, possíveis erros podem ser encontrados graças à exibição dos campos nesta tabela. Caso esta opção não esteja selecionada, qualquer alteração na query SQL não reflete automaticamente abaixo, o que necessitará clicar no botão Read Fields. Confirme logo após no botão OK.

Figura 18 – Query final gerada pela caixa de diálogo SQL Query Designer

Desenhando o relatório O desenho do relatório será uma etapa importante para a sua compreensão prática dos elementos existentes para se criar um e também sobre as bands (bandas) em sua geração. Para começar na criação do desenho do relatório, você vai configurar inicialmente as bands que não serão exibidas. Com o cursor entre uma band e outra, você deve arrastar para cima, até que ela se encontre com a superior. Isso diminui a sua altura até zero, o que é exatamente o valor necessário para esta desaparecer. As alturas de cada band para a criação do relatório é exibida conforme a Tabela 2 mostrada a seguir:

Page 82: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

8282

Tabela 2 – Alturas das bands utilizadas na construção do relatório Band Altura da Banda title 0 pageHeader Mantenha como está columnHeader Mantenha como está detail Mantenha como está columnFooter 0 pageFooter Mantenha como está summary Mantenha como está Atenção: Você pode configurar as propriedades de cada band selecionando-a através da janela Outline Window e alterando em Properties, no campo Band height. Neste caso, a alteração não precisa ser aplicada (alterou o valor da propriedade, confirmou com a tecla ENTER, mudou).

Adicionando os textos estáticos Antes de iniciar a criação do desenho, você tem na Figura 19 como será o resultado final. Veja no quadro “Construindo o design do relatório” para criá-lo.

Figura 19 – Aparência final do relatório no Designer

Construindo o design do relatório

Para criar a aparência vista na Figura 19, os seguintes passos serão feitos: 1. Na janela Palette, arraste o elemento Static Text (Label) e o dimensione a um tamanho

qualquer na band pageHeader. Dê um duplo clique neste elemento desenhado e digite: Autores Cadastrados. Na janela Properties altere em Font Size para 24 e clique no botão Bold. Mude também para Center em Horizontal Alignment e para Middle em Vertical Alignment.

2. Na categoria Box properties, na janela Properties, com o label Autores Cadastrados selecionado, altere Border para 1 Point e coloque None em Left Border e Right Border.

3. Adicione um elemento Rectangle na band columnHeader e altere a cor em Background a sua escolha, na janela Properties.

Page 83: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

8383

4. Adicione quatro elementos Static Text sobre o elemento Rectangle adicionado. Digite ID, Nome, E-mail e Nascimento respectivamente (ver Figura 19). Altere seu tamanho a sua escolha e coloque em Bold. Para alinhar, o editor visual do iReport para NetBeans possui linhas auxiliares para o alinhamento, herdado do Sun's Visual Library API do NetBeans.

5. Na janela Outline, expanda Fields e arraste cada campo para a band detail, no Design. Olhe a posição conforme a Figura 19 apresenta. Dimensione a largura de cada componente a gosto. Observe os campos arrastados são Text Fields.

Figura 20 – Fields criados a partir da instrução SQL gerada

6. Selecione, no Design, o Text Field que representa o campo nascimento. Na janela Properties, vá até o item Pattern e de um clique no botão com três pontos ou em sua seleção, pressione Ctrl+Space. Na caixa de diálogo Text field – Pattern, selecione Date em Category e em Type selecione o formato de data usado no Brasil. Observe na parte inferior, em Pattern, o formato dd/MM/yyyy.

Figura 21 – Seleção do pattern para o formato de data

Page 84: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

8484

7. Expanda Variables, na janela Outline, e arraste para a band pageFooter e o posicione no

canto direito.

Figura 22 – A variável PAGE_NUMBER selecionada

8. Para finalizar, adicione um Static Text ao lado desta variável PAGE_NUMBER e digite Página:.

Clique em Preview para visualizar o relatório. Observe que os dados encontrados na band detail serão repetidos até o seu fim, criando uma nova página sucessivamente até a última linha encontrada em sua tabela. Na parte inferior você vê o número da página.

Figura 23 – Preview do relatório criado Em caso de erro, observe a saída encontrada na parte inferior, na janela iReport output.

Page 85: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

8585

Figura 24 – Saída executada pelo iReport para NetBeans na compilação e exibição do relatório

Configurando o NetBeans IDE 6.0 para executar seu relatório A primeira providência a fazer é configurar as bibliotecas para gerar os relatórios no NetBeans IDE 6.0. Para compilar sua aplicação, você vai precisar de sete arquivos JARs, para este caso, listados a seguir:

1. commons-beanutils-1.7.jar 2. commons-collections-2.1.jar 3. commons-digester-1.7.jar 4. commons-javaflow-20060411.jar 5. commons-logging-api-1.0.2.jar 6. itext-1.3.1.jar 7. jasperreports-2.0.4.jar

Como o iReport para NetBeans necessita de tais bibliotecas para executar, você pode encontrá-las no CD-ROM anexo ao livro, compactado no diretório de jasperreports, em lib. Vá ao menu Tools e clique no item Libraries.

Figura 25 – Selecionando Libraries pelo menu Tools

Page 86: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

8686

Na caixa de diálogo Library Manager, clique no botão New Library. Na caixa de diálogo New Library digite JasperReports (se desejar colocar a versão também, é interessante) no campo Library Name e clique no botão OK para confirmar. Retornando a caixa de diálogo Library Manager, clique no botão Add JAR/Folder. Selecione os arquivos .jar citados do JasperReports anteriormente e confirme. Retornando, você terá os arquivos configurados no campo Library Classpath da guia Classpath.

Figura 26 – Bibliotecas do JasperReports

Adicionando as bibliotecas para rodar o relatório Na janela Projects, clique com o direito do mouse sobre Libraries, com seu projeto expandido, e selecione Add Library no menu de contexto. Na caixa de diálogo Add Library, selecione com JasperReports (a biblioteca criada anteriormente) e MySQL, com o Ctrl pressionado. Confirme clicando no botão Add Library.

Criando o Servlet que chamará o relatório Sobre o projeto, clique com o direito do mouse, em Projects, e selecione o item New, clicando em Servlet. Na caixa de diálogo New Servlet, digite Relatorio em Class Name. Adicione um pacote em Package (no caso do livro, seria br.com.integrator). Clique no botão Finish para completar. Adicione no Servlet o código mostrado na Listagem 1 a seguir e salve. Listagem 1 – Trecho do Servlet Relatorio contendo a chamada ao arquivo JasperReports //... omitido por não haver alterações protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletOutputStream servletOutputStream = response.getOutputStream(); String caminho = "/relatorio/"; String relatorio = caminho+"relatorio.jasper"; InputStream reportStream =

Page 87: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

8787

getServletConfig().getServletContext().getResourceAsStream(relatorio); Connection connection = null; try { //cria a conexão com o banco de dados Class.forName("com.mysql.jdbc.Driver"); String db = "jdbc:mysql://localhost:3306/livraria"; connection = (Connection) DriverManager.getConnection(db,"edson","integrator"); // envia o relatório em formato PDF para o browser response.setContentType("application/pdf"); //para gerar o relatório no formato PDF // o método runReportToPdfStream foi usado JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream, new HashMap(),connection); } catch (ClassNotFoundException ex) { Logger.getLogger(Relatorio.class.getName()).log(Level.SEVERE, null, ex); } catch (SQLException ex) { Logger.getLogger(Relatorio.class.getName()).log(Level.SEVERE, null, ex); } catch (JRException e) { Logger.getLogger(Relatorio.class.getName()).log(Level.SEVERE, null, e); } finally{ servletOutputStream.flush(); servletOutputStream.close(); try { if (connection != null) { connection.close(); } } catch (SQLException ex) { Logger.getLogger(Relatorio.class.getName()).log(Level.SEVERE, null, ex); } } } Para as importações dos objetos encontrados, utilize o atalho Ctrl + Shift + I (Fix All Imports).

Figura 27 – Importação com Fix All Imports

Page 88: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

8888

Toda a lógica necessária para a criação do relatório está no método protegido processRequest(). Este método, configurado para ser chamado tanto via método POST e GET, utiliza o método runReportToPdfStream(). Este método, de JasperRunManager, cria uma instância de java.io.OutputStream() para escrever o relatório compilado e possui os seguintes parâmetros: runReportToPdfStream(java.io.InputStream inputStream, java.io.OutputStream outputStream, java.util.Map parameters, JRDataSource dataSource) Para exibir o relatório no browser, você precisa passar o relatório criado para um stream de dados. É exatamente isso que ocorre no primeiro parâmetro deste método. O relatório é pego em uma String e depois convertido em um InputStream, no seguinte trecho: String caminho = "/relatorio/"; String relatorio = caminho + "relatorio.jasper"; InputStream reportStream = getServletConfig(). getServletContext(). getResourceAsStream(relatorio); O segundo parâmetro é a resposta, que é definida em um ServletOutputStream, através do seguinte trecho: ServletOutputStream servletOutputStream = response.getOutputStream(); O terceiro parâmetro é o HashMap necessário para transmitir algum parâmetro para o seu relatório, caso este o tenha. Por último foi transmitida a conexão, para que o relatório executasse com sucesso. A saída foi definida pelo setContentType(), que através do objeto response, possibilitou a finalização com o MIME TYPE para que o browser o reconheça como PDF. Atenção: O exemplo passado do Servlet, define apenas um modelo didático, não sendo ideal para sistemas em produção. Recomendo o conhecimento de Design Patterns.

A página que chamará o Servlet Você mesmo pode criar se desejar, uma página que chamará seu Servlet. O trecho a seguir mostra a chamada ao Servlet, lembrando que o nome dado está configurado no deployment descriptor (web.xml), que para o caso deste livro, será gerado automaticamente pela IDE. Portanto, abra o arquivo index.jsp e adicione o pequeno trecho mostrado na Listagem 2 a seguir: Listagem 2 – Alteração do arquivo index.jsp <%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Relatórios JasperReports</title> </head> <body> <a href="Relatorio">Clique aqui para visualizar seu relatório</a> </body> </html>

Page 89: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

8989

Figura 28 – Relatório exibido no browser após sua chamada

Trabalhando com parâmetros em seus relatórios O primeiro exemplo demonstra somente a chamada ao relatório criado, sem transmitir parâmetros. Para o segundo exemplo, você vai adicionar um parâmetro ao relatório. Para fazer este, abra o projeto do Capítulo 4, TrabComPadroes. Adicione um diretório chamado relatorio e copie para este o relatório criado.

Figura 29 – Exibição do projeto TrabComPadroes contendo o relatorio.jrxml Abra o arquivo relatorio.jrxml. Na janela Outline, clique com o direito do mouse sobre Parameters e no menu de contexto selecione parameter em Add.

Page 90: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

9090

Figura 30 – Adicionando um parâmetro pelo menu de contexto Com o parâmetro criado e selecionado, vá até a janela Properties e altere os campos como mostra a Tabela 3: Tabela 3 – Propriedades do parâmetro criado Propriedade Valor Name ID Parameter Class java.lang.Integer Default value expression new Integer(0)

Figura 31 – Propriedades alteradas do parâmetro adicionado Abra a caixa de diálogo Report Query, e altere a query como mostrado na Listagem 3 a seguir: Listagem 3 – Alteração da query usada no relatório SELECT * FROM Autores WHERE id=$P{ID}

Page 91: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

9191

Figura 32 – Alteração da instrução SQL Feche a caixa de diálogo e clique em Preview para gerar o arquivo .jasper.

Adicionando o Servlet Relatorio Crie um Servlet chamado Relatorio e adicione o conteúdo similar ao mostrado na Listagem 4 a seguir: Listagem 4 – O Servlet Relatorio //...omitido por não haver alterações protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletOutputStream servletOutputStream = response.getOutputStream(); String caminho = "/relatorio/"; String relatorio = caminho + "relatorio.jasper"; InputStream reportStream = getServletConfig().getServletContext(). getResourceAsStream(relatorio); Connection connection = null; String id = request.getParameter("id"); try { //chama a conexão da fábrica de conexões connection = (Connection) ConnectionFactory.getConnection( ); HashMap<String, Integer> parameterMap = new HashMap<String, Integer>(); //o Nome do parâmetro e o valor é passado ao HashMap parameterMap.put("ID", Integer.parseInt(id)); // envia o relatório em formato PDF para o browser response.setContentType("application/pdf");

Page 92: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

9292

//para gerar o relatório em PDF // o método runReportToPdfStream foi usado JasperRunManager.runReportToPdfStream(reportStream, servletOutputStream, parameterMap,connection); } catch (Exception ex) { Logger.getLogger(Relatorio.class.getName()).log(Level.SEVERE, null, ex); }finally{ servletOutputStream.flush(); servletOutputStream.close(); try { //fecha a conexão ConnectionFactory.closeConnection(connection); } catch (Exception ex) { Logger.getLogger(Relatorio.class.getName()).log(Level.SEVERE, null, ex); } } O parâmetro passado é um java.util.HashMap(), que define se haverá um ou mais parâmetros. O parâmetro criado no relatório possui um nome, e é este que deve ser utilizado neste HashMap: ID (referindo-se a $P{ID}. Como se trata de uma chave string e de um valor numérico inteiro, graças ao método put(Key, Value), o exemplo capturará o campo chave de cada autor e o transmitirá ao parâmetro, da seguinte forma: String id = request.getParameter("id"); parameterMap.put("ID", Integer.parseInt(id));

Chamando o Servlet para gerar o relatório Abra o arquivo mostrarAutoresCads.jsp e adicione mais uma coluna a tabela, sendo que neste última haverá a chamada ao servlet Relatorio, como mostra o detalhe na Listagem 5 a seguir: Listagem 5 – Chamando o Servlet por mostrarAutoresCads.jsp <%@page contentType="text/html" pageEncoding="ISO-8859-1"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Trabalhando com DAO e Model 2</title> </head> <body> <table border="1" cellpadding="2" cellspacing="0"> <tr> <th>ID - Atualizar</th> <th>Nome</th> <th>E-mail</th> <th>Nascimento</th> <th>Excluir Autor</th> <th>Em PDF</th> </tr> <c:forEach var="lista" items="${ requestScope.autoresList }"> <tr> <td> <a href="ServletAutores?cmd=atu&id=${lista.id}"> ${lista.id} </a> </td>

Page 93: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

9393

<td>${lista.nome}</td> <td>${lista.email}</td> <td><fmt:formatDate value="${lista.nascimento}" type="DATE" pattern="dd/MM/yyyy"/> </td> <td> <a href="ServletAutores?cmd=exc&id=${lista.id}"> Excluir </a> </td> <td> <a href="Relatorio?id=${lista.id}"> Visualizar este autor </a> </td> </tr> </c:forEach> </table> <br /> <a href="formInserindoDados.jsp">Adicionar um novo Autor</a> <br /> <a href="index.jsp">Página Principal</a> </body> </html>

Figura 33 – Exibição da chamada ao relatório Atenção: No CD-ROM há um vídeo que ensina a criar seu relatório usando o assistente.

Page 94: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

9494

Capítulo Extra 5 

Estudo de caso completo com Visual Web JSF Este capítulo extra é a continuação do sistema iniciado nos Capítulos 7 e 8, sendo que sem a leitura destes, será mais difícil sua execução.

Adicionando novas características ao administrador Enquanto que no livro você pôde criar uma aplicação com os elementos fundamentais do Visual Web JSF, entendendo os detalhes de como funcionam, neste capítulo extra, será finalizada toda a área administrativa, adicionando relacionamento às tabelas. Além disso, outros componentes serão usados, integrando-se para criar uma área administrativa mais complexa. Neste capítulo será apresentado:

• A criação de mais três entidades (tabelas); • Utilização de campos ocultos; • Transmitindo dados via HTTP, pelo método GET; • Utilizando o componente Listbox com banco de dados;

As entidades e seus relacionamentos No decorrer do livro, duas tabelas foram utilizadas para o desenvolvimento do administrador do aplicativo Web: livros e autores. Agora, será necessário criar três novas tabelas: editoras, publicacao e livro_autor.

Figura 1 – Modelo de dados do projeto A Listagem 1 mostra o script para a criação das tabelas que serão adicionadas (veja o quadro

“Utilizando o NetBeans para instruções SQL”) no banco de dados de livraria.

Page 95: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

9595

Listagem 1. Script para criação das tabelas do projeto CREATE TABLE editoras ( id int(11) NOT NULL auto_increment, editora varchar(50) default NULL, PRIMARY KEY (id) ) ENGINE=InnoDB; CREATE TABLE publicacao ( id int(11) NOT NULL auto_increment, livro_id int(11) default NULL, editora_id int(11) default NULL, PRIMARY KEY (id), /* Foreign keys */ KEY fk_livro (livro_id), KEY fk_editora (editora_id), CONSTRAINT fk_editora FOREIGN KEY (editora_id) REFERENCES editoras (id) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT fk_livro FOREIGN KEY (livro_id) REFERENCES livros (id) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB; CREATE TABLE livro_autor ( livro_id int, autor_id int, /* Foreign keys */ CONSTRAINT fk_autor_livro FOREIGN KEY (autor_id) REFERENCES autores(id) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT fk_livro_autor FOREIGN KEY (livro_id) REFERENCES livros(id) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE = InnoDB;

Entendendo o relacionamento Quando um livro, uma editora e um autor são cadastrados, podemos relacioná-los. Um livro pode pertencer a um ou mais autores, quanto que a publicação geralmente é feita em somente uma editora. Desta forma, se o livro “X”, foi escrito pelos autores “A”, “B” e “C”, será publicado pela editora “Ciência Moderna. Logo, podemos ter muitos autores para um determinado livro ou um autor para muitos livros. Esta é a modelagem mais simples de se entender. Para que haja a relação entre autor e livro (ou vice-versa), temos uma tabela que possui o relacionamento Many-To-Many (Muitos-para-Muitos), ao qual armazenará o código do autor e do seu respectivo livro escrito. É evidente que na tabela de livros temos os campos publicacao e edicao, que devem ser transferidos para a tabela publicacao, mas que não fora feito para apenas estender o exemplo do livro.

Page 96: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

9696

Utilizando o NetBeans para instruções SQL

No NetBeans, para executar o script da Listagem 1, siga os passos descritos a seguir: 1. Tenha conectado seu banco de dados, como descrito no livro através do Capítulo 4 em “Se

conectando ao banco de dados”; 2. Com o direito do mouse sobre Tables>Execute Command, digite o script das tabelas na

janela SQL Command 1 e clique no botão Run SQL(Ctrl+Shift+E) (veja detalhes na Figura 4.9 do livro);

3. Verifique a saída na janela Output>SQL Command 1 Execution; 4. Para exibir as tabelas criadas, vá em Services>“selecione a sua conexão”>Tables e, com o

direito do mouse, selecione Refresh no menu de contexto. Atenção: Adicione o driver JDBC do MySQL ao projeto.

Adicionando novas páginas do administrador A página responsável pelo cadastro de editoras é o mais simples, portanto será apresentada inicialmente. Crie uma nova página Visual Web JSF Page chamada de Editora, dentro do diretório admin. A Figura 2 exibe como esta será formada e no quadro “Componentes da página Editora” há uma descrição dos elementos que compõe a página.

Figura 2 – A página administrativa de cadastro de editoras

Page 97: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

9797

Componentes da página Editora

Siga estes passos para a página Editora, conforme visto na Figura 2: 1. Adicione um componente Page Fragment Box e selecione o menu do administrador.

Posicione-o como os demais já feitos; 2. Arraste da janela Palette o componente Label para o Design da página. Posicione-o e digite

Editora: (altere em text na janela Properties se necessário); 3. Arraste um componente Text Field, ao lado do rótulo inserido. Altere a propriedade id através

de Properties para tfEditora; 4. Adicione o componente Button na página e altere em Properties a propriedade id para

btSalvar e text para Salvar; 5. Para finalizar o formulário, adicione o componente Message Group logo abaixo do

formulário; 6. Adicione um componente Table abaixo do formulário. Arraste da janela Services, através da

tabela editoras (se não estiver aparecendo, clique com o direito sobre Tables, na sua conexão, e selecione Refresh). Com o direito sobre ela, selecione Table Layout. Altere as propriedades de Header Text das duas colunas e adicione duas novas, chamando uma de Excluir e Atualizar, alterando também em Value Expression neste caso. Nas duas colunas adicionadas, mude também a propriedade Component Type para Hyperlink. Se desejar, coloque paginação;

7. No Design, selecione o link Excluir da tabela adicionada e em Properties altere o id para excluir. Faça o mesmo para o link Atualizar modificando para atualizar;

8. Para finalizar o componente Table, vá à janela Properties e desça a rolagem até o item Advanced e marque a opção internalVirtualForm. Veja detalhes no Capítulo 8 a respeito.

O bean Editora Assim como feito nos demais exemplos de cadastro criados no livro, para o cadastro de editora haverá um JavaBean específico. A Listagem 2 exibe o código deste bean: Listagem 2. O bean Editora public class EditoraBean { private RowKey rowKey; private String editora; public RowKey getRowKey() { return rowKey; } public void setRowKey(RowKey rowKey) { this.rowKey = rowKey; } public String getEditora() { return editora; } public void setEditora(String editora) { this.editora = editora; } } A explicação da Listagem 2 é a mesma elaborada no livro, no Capítulo 8.

Page 98: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

9898

Os códigos do botão e dos links Como já sabe, basta dar um duplo clique em cada elemento e definir seu código. A seguir você possui as listagens contendo os códigos de cada elemento: Listagem 3. O código do link Excluir do componente Table da página public String excluir_action() { try { //captura a linha atual do link de exclusão clicado RowKey rowKey = tableRowGroup1.getRowKey(); if (rowKey != null) { //atualiza o cache para iniciar a exclusão editorasDataProvider.refresh(); //remove a linha existente no objeto editorasDataProvider editorasDataProvider.removeRow(rowKey); //reflete esta ação no banco de dados editorasDataProvider.commitChanges(); //atualiza o cache para exibir no componente Table editorasDataProvider.refresh(); } //limpa os campos existentes tfEditora.setText(null); //torna nulo o valor de rowkey em EditoraBean getSessionBean1().getEditoraBean().setRowKey(null); //informa ao administrador a exclusão info("Editora excluída!"); } catch (Exception ex) { editorasDataProvider.revertChanges(); editorasDataProvider.refresh(); error("Erro encontrado: " + ex); } //retorna nulo pois não muda a página return null; } Listagem 4. O código do link Atualizar do componente Table da página public String atualizar_action() { try { //leva para o bean EditoraBean os valores existentes //nas linhas adicionadas editoraBean = getSessionBean1().getEditoraBean(); // captura a linha atual do componente Table TableRowDataProvider rowData = (TableRowDataProvider) getBean("currentRow"); // adiciona os valores dos campos e principalmente o RowKey // no Bean EditoraBean editoraBean.setRowKey(rowData.getTableRow()); editoraBean.setEditora((String) rowData.getValue("editoras.editora")); } catch (Exception ex) { //informa o erro caso ocorra ao administrador error("Erro encontrado: " + ex); } //retorna nulo pois não muda a página return null; }

Page 99: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

9999

Listagem 5. O código do botão Salvar do formulário da página public String btSalvar_action() { try { RowKey rowKey = getSessionBean1().getEditoraBean().getRowKey(); String mensagem; if (rowKey == null) { //prepara uma nova linha para inserção de dados rowKey = editorasDataProvider.appendRow(); mensagem = "Adicionado com sucesso!"; } else { //atualiza o cache para iniciar a atualização editorasDataProvider.refresh(); mensagem = "Atualizado com sucesso!"; } //captura o valor do componente no formulário //e o atribui a seu determinado campo no banco de dados editorasDataProvider.setValue("editoras.editora", rowKey, tfEditora.getText()); //grava as informações no banco de dados editorasDataProvider.commitChanges(); //limpa os campos existentes tfEditora.setText(null); //torna nulo o valor de rowkey em EditoraBean getSessionBean1().getEditoraBean().setRowKey(null); //informa ao administrador o cadastro efetuado info(mensagem); editorasDataProvider.refresh(); } catch (Exception ex) { //informa o erro caso ocorra ao administrador error("Não foi possível adicionar" + ex.getMessage()); editorasDataProvider.revertChanges(); } //retorna nulo pois não muda a página return null; } As Listagem 3, 4 e 5 exibem cada um dos componentes que terão seu comportamento determinado por suas ações, conforme já visto em outros cadastros feitos no livro. Portanto, a explicação será omitida.

Alterando o método prerender() Como já visto no livro, através do Capítulo 8, o método callback prerender() será alterado para preencher o Text Field tfEditora para que este exiba o texto do nome da editora selecionado através do componente Table da página. Listagem 6. O código do método Callback prerender() da página public void prerender() { //verifica se RowKey não é nulo if(getSessionBean1().getEditoraBean().getRowKey()!=null){ tfEditora.setText(editoraBean.getEditora()); } }

Declarando a variável editoraBean Ao longo das listagens, fora utilizado uma variável editoraBean, que deve ser declarada como mostrado a seguir, no código da página: EditoraBean editoraBean = new EditoraBean();

Page 100: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

100100

A página de criar publicações A página de publicações possui um aspecto diferente das páginas já criadas. Seu propósito é ligar uma Editora a um determinado Livro. Para escolher as editoras, você utilizará um componente Drop Down List, que exibirá todas as editoras cadastradas e enviará o valor chaves da selecionada para o cadastro. O livro selecionado será armazenado em um campo oculto, que será incluído na página através do componente Hidden Field. Crie uma página Visual Web JSF Page chamada de Publicar. Adicione os componentes exibidos na Figura 3, incluindo o componente Drop Down List.

Figura 3 – Aparência da página Publicar A Tabela 1 mostra os componentes que terão suas propriedades alteradas. Tabela 1 – Alteração das propriedades dos componentes do formulário da página Componente Propriedade Valor Static Text text Editoras Cadastradas Label text Editoras: Drop Down List id editoras Button text Publicar id btPublicar Hidden Field* id id * Para alterar as propriedades do componente Hidden Field, cuja aparência não é exibida no design da página, selecione-o através da janela Navigator (veja número 2 na Figura 3).

Configurando o componente Drop Down List editoras Arraste Services>Tables>editoras para a página. O Visual Web JSF irá questioná-lo, através da caixa de diálogo Add New Data Provider with RowSet for Table editoras. Esta caixa de diálogo está reconhecendo que já há em SessionBean1 um RowSet para editoras, selecionando já todos os

Page 101: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

101101

dados desta tabela. Como vamos usar o mesmo para exibir no componente Drop Down List, mantenha a opção Use, que foi sugerida, selecionada e confirme.

Figura 4 – Adicionando um novo data provider Clique com o direito do mouse sobre o componente Drop Down List editoras e selecione, no menu de contexto, o item Bind to Data (veja Figura 5).

Figura 5 – Selecionando Bind to Data no menu de contexto

Page 102: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

102102

Na caixa de diálogo Bind to Data, selecione a guia Bind to Data Provider. Em Choose a Data Provider to bind to editoras o item editorasDataProvider. Automaticamente o Visual Web JSF selecionará em Value field o campo chave, que no caso será editoras.id e em Display field o item editoras.editora. Caso isso não ocorra, deverá ser selecionado manualmente.

Figura 6 – Ligando o data provider ao componente Drop Down List editoras Observando o diálogo (ver Figura 6), você deve ter concluído que serão exibidos os textos com os nomes das editoras e, o item selecionado transmitido para ser salvo, será o valor do código chave.

Arrastando a tabela publicacao para a página Como os dados envolvidos no formulário desta página serão salvos na tabela publicacao, arraste-a para a página (SEM ser sobre quaisquer componentes exibidos). Verifique que em Navigator agora há o Data Provider chamado publicacaoDataProvider dentro do nó de Publicar.

Adicionando código ao botão Publicar Dê um duplo clique no componente Button btPublicar e adicione o código da Listagem 7. Listagem 7. O código do botão btPublicar do formulário da página public String btPublicar_action() { try { //prepara uma nova linha para inserção de dados RowKey rowKey = publicacaoDataProvider.appendRow(); //captura os valores de cada componente no formulário //e os atribui a seus determinados campos no banco de dados publicacaoDataProvider.setValue("publicacao.livro_id", rowKey, id.getText()); publicacaoDataProvider.setValue("publicacao.editora_id", rowKey, editoras.getValue());

Page 103: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

103103

//grava as informações no banco de dados publicacaoDataProvider.commitChanges(); //retorna a seguinte string em caso de sucesso return "publicado"; } catch (Exception e) { //em caso de erro, exibe ao usuário error("Erro: " + e.getMessage()); //reverte alterações feitas no data provider publicacaoDataProvider.revertChanges(); } //retorna nulo em caso de erro, não mudando de página return null; } Observando a Listagem 7, percebemos que a captura do valor de um componente Hidden Field é similar ao Text Field, através do método getText(). Para o componente Drop Down List editoras, utilizamos o método getValue() para capturar o valor selecionado. Ao realizar com sucesso, este botão retorna a string “publicar”, o que indica que o usuário será direcionado a outra página.

Adicionando código a página Continuando no código, você deverá alterar algumas partes para que possa executar certas ações que caracterização o seu uso. A Listagem 8 exibe o que será alterado. Listagem 8. Alterações do código da página //...omitido por não ser alterado public void prerender() { //captura a variavel GET titulo this.setTitulo((String) getExternalContext(). getRequestParameterMap().get("titulo")); } //...omitido por não ser alterado

private String livid; public String getLivid() { return livid; } public void setLivid(String livid) { this.livid = livid; } private String titulo; public String getTitulo() { return titulo; } public void setTitulo(String titulo) { this.titulo = titulo; } //...omitido por não ser alterado

Page 104: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

104104

No código do método prerender() exibido na Listagem 8, exibe um novo método não utilizado até o momento. Através de getExternalContext(), você tem acesso ao método getRequestParameterMap(), que possibilita, através de get(), capturar o valor de uma variável transmitida pelo método GET. Isso significa que transmitiremos uma variável pelo cabeçalho HTTP da página (barra de endereços) chamada de “titulo”. Esta variável será capturada e utilizada pela página. Veja mais adiante a explicação do que será transmitido. A segunda forma de receber dados pelo método GET através de uma página criada pelo Visual Web JSF é similar ao utilizado pelo JavaServer Faces, utilizando getters e setters. Como exemplo, a variável livid será utilizada para este fim.

Configurando o Hidden Field id e o título da página Volte ao Design da página. Selecione na janela Navigator a página Publicar. Vá à janela Properties e clique no botão com três pontos em Title. Altere como mostrado no trecho a seguir, na caixa de diálogo Title: Publicar livro #{admin$Publicar.titulo} Seu exemplo deverá ser similar ao da Figura 7.

Figura 7 – Alteração da propriedade Title da página Faça o mesmo com o campo oculto (Hidden Field) id. Selecione-o através da janela Navigator e na propriedade text clique no botão de três pontos. Em Use bind, selecione Bind to an Object e expanda admin/Publicar. Selecione livid e confirme.

Page 105: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

105105

Figura 8 – Bind para a variável livid

Transmitindo via método GET Abra a página Livro.jsp, de admin, e adicione uma nova coluna ao componente Table da página. Esta nova coluna terá um Hyperlink como tipo de componente (Component Type). Em Header Text digite Publicação e em Value Expression digite Gerar. Veja os detalhes na Figura 9.

Page 106: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

106106

Figura 9 – A nova coluna chamada de Publicação Selecione o link Gerar, em destaque na Figura 10, e vá até suas propriedades. Dê um clique no botão de três pontos na propriedade url.

Figura 10 – A coluna Publicação e seu link Gerar

Page 107: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

107107

Digite em URL, mantendo Use value, como mostrado a seguir: /admin/Publicar.faces?livid=#{currentRow.value['livros.id']}&titulo=#{currentRow.value['livros.titulo']} O que será transmitido via URL foi colorido da seguinte forma:

• Em vermelho – temos as variáveis que serão transmitidas; • Em azul – temos os valores destas variáveis, que correspondem a valores das colunas do

banco de dados; • Em verde – a concatenação para envio de mais de uma variável, o que ocorre no caso.

Figura 11 - Alteração no campo URL de Gerar

Configurando faces­config.xml para trabalhar com GET Para capturar um valor transmitido pelo método GET no JavaServer Faces, utilizamos o <managed-property/>, que deve possuir em seu valor a expressão #{param.VARIAVEL}. Veja na Listagem 9 como ficará a alteração feita no arquivo faces-config.xml: Listagem 9. Alteração em faces-config.xml para a página Publicar <managed-bean> <managed-bean-name>admin$Publicar</managed-bean-name> <managed-bean-class>br.com.integrator.admin.Publicar</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> <managed-property> <property-name>livid</property-name> <value>#{param.livid}</value> </managed-property> </managed-bean>

Page 108: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

108108

A página de publicações Crie uma nova página Visual Web JSF Page chamada de Publicados. Adicione os componentes da Figura 12 a seguir. Altere o componente Table como o quadro “Exibindo as Publicações Cadastradas” descreve.

Figura 12 – Design da página Publicados

Exibindo as Publicações Cadastradas

Siga estes passos para o componente Table da página Publicados, conforme visto na Figura 12: 1. Arraste de Services>SUA CONEXAO>Tables a tabela publicacao para a página (NÃO

faça sobre o componente Table); 2. Assim como já ocorrido em caso anterior, o Visual Web JSF irá questioná-lo, através da

caixa de diálogo Add New Data Provider with RowSet for Table publicacao. Selecione desta vez a opção Create em admin/Publicados e confirme;

3. Expanda o nó de Publicados, na janela Navigator, e dê um duplo clique em publicacaoRowSet;

4. Ao surgir o Design Query, clique com o direito do mouse e selecione Add Table na parte superior da janela (veja detalhe na Figura 13). Adicione as tabelas editoras e livros;

5. Deixe marcado somente os campos para sua query: publicacao.id, editoras.editora e livros.titulo;

6. Volte à página Publicados, em Design, e com o direito do mouse sobre o componente Table, vá até Table Layout;

7. Altere a ordem e os títulos em Header Text na seqüência: ID, Editora, Título; 8. Na guia Options digite no campo Title “Publicações Cadastradas” e no campo Empty

Data Message “Não há publicações no Momento”. Se desejar, marque Enable Pagination e confirme.

Page 109: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

109109

Figura 13 – A query relacionada

Vinculando o livro a seus autores Diferente do link Gerar, que foi transmitido via método GET, o link que será criado agora transmitirá via método POST, mas sem usar uma sessão. Abra a classe RequestBean1 e adicione em seu final o trecho da Listagem 10. Listagem 10. Alteração na classe RequestBean1 //... omitidos por não haver alterações private String livid; public String getLivid() { return livid; } public void setLivid(String livid) { this.livid = livid; }

Page 110: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

110110

Alterando novamente a página Livro Na página de cadastro de Livros (Livro.jsp), adicione mais uma coluna no componente Table e mova antes da coluna de Publicações, deixando-a similar a Figura 14 mostrada a seguir:

Figura 14 – Nova coluna Autor na tabela da página Livros Selecione o link Adicionar da coluna Autor, do componente Table, e altere a propriedade id para adicionar (Figura 15).

Figura 15 – Propriedade id alterada do link Adicionar do componente Table

Adicionando código ao link Adicionar Dê um duplo clique no link Adicionar, do componente Table, da página Livro e adicione o código mostrado a seguir na Listagem 11: Listagem 11. Código do link Adicionar public String adicionar_action() { //captura a linha atual do link de adição clicado TableRowDataProvider rowData = (TableRowDataProvider) getBean("currentRow"); //o coloca no bean RequestBean1 para que possa transmitir //o valor para a página LivroAutor getRequestBean1().setLivid(rowData.getValue("livros.id").toString()); return "adlivroautor"; }

Page 111: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

111111

O código deste link simplesmente adicionará o ID do livro selecionado, no componente Table, a livid de RequestBean1, criado anteriormente para ser puxado pela página que irá vincular o autor ao livro.

A página de adição de autor ao livro Crie uma página similar a Figura 16, alterando as propriedades conforme a Tabela 2.

Figura 16 – Vinculando o livro aos autores Tabela 2 – Alteração das propriedades dos componentes do formulário da página Componente Propriedade Valor Static Text text Vincular Autor ao Livro Label text Autores: Drop Down List id autores Button text Adicionar ao Livro id btAdLivro

Configurando o componente Drop Down List autores Arraste Services>Tables>autores para a página. O Visual Web JSF irá questioná-lo, através da caixa de diálogo Add New Data Provider with RowSet for Table autores. Ao ser questionado quanto a criação do Data Provider, mantenha a opção Use, que foi sugerida, selecionada e confirme. Clique com o direito do mouse sobre o componente Drop Down List autores e selecione, no menu de contexto, o item Bind to Data (similar ao da Figura 5 em exemplo anterior). Na caixa de diálogo Bind to Data, selecione a guia Bind to Data Provider. Em Choose a Data Provider to bind to autores o item autoresDataProvider. Automaticamente o Visual Web JSF

Page 112: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

112112

selecionará em Value field o campo chave, que no caso será autores.id e em Display field o item autores.nome. Caso isso não ocorra, deverá ser selecionado manualmente. Confirme.

Figura 17 – Bind to Data para o componente Drop Down Listo autores

O código do botão do formulário Dê um duplo clique no botão Adicionar ao Livro e adicione o código da Listagem 12. Listagem 12. Código do botão Adicionar ao Livro public String btAdLivro_action() { //capta o id do livro em getRequestBean1() String livid = getRequestBean1().getLivid(); try { //prepara uma nova linha para inserção de dados RowKey rowKey = livro_autorDataProvider.appendRow(); //captura os valores de cada componente no formulário //e os atribui a seus determinados campos no banco de dados livro_autorDataProvider.setValue("livro_autor.livro_id", rowKey, livid); livro_autorDataProvider.setValue("livro_autor.autor_id", rowKey, autores.getValue()); //grava as informações no banco de dados livro_autorDataProvider.commitChanges(); //retorna a string publicado return "publicado"; } catch (Exception e) { error("Erro: " + e.getMessage()); } //não vai a página alguma caso haja um erro return null;

Page 113: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

113113

} Similar ao criado para vincular um livro a uma publicação e sua respectiva editora, neste caso, a diferença fica por conta de não estarmos usando o envio dos dados via método GET, mas não colocando os dados em Sessão, como já fora feito em outros exemplos.

A página de autores publicados A última página Visual Web JSF Page a ser criada no administrador será AutoresPublicados. Sua aparência será similar a Figura 18. Altere o componente Table como o quadro “Exibindo os Autores Publicados” descreve.

Figura 18 – Design da página AutoresPublicados

Exibindo os Autores Publicados

Siga estes passos para o componente Table da página Publicados, conforme visto na Figura 18: 1. Arraste de Services>SUA CONEXAO>Tables a tabela livro_autor para a página (NÃO

faça sobre o componente Table); 2. Expanda o nó de AutoresPublicados, na janela Navigator, e dê um duplo clique em

livro_autorDataProvider; 3. Ao surgir o Design Query, clique com o direito do mouse e selecione Add Table na parte

superior da janela. Adicione as tabelas autores e livros (veja o resultado final na Figura 19);

4. Deixe marcado somente os campos para sua query: autores.nome e livros.titulo; 5. Volte à página AutoresPublicados, em Design, e com o direito do mouse sobre o

componente Table, vá até Table Layout; 6. Deixe a ordem dos títulos em Header Text na seqüência: Título e Autor; 7. Na guia Options digite no campo Title “Autores publicados” e no campo Empty Data

Message “Não há autores com livros cadastrados”. Se desejar, marque Enable Pagination e confirme.

Page 114: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

114114

Figura 19 – A query relacionada

A navegação em faces­config.xml Vá ao arquivo faces-config.xml e altere a navegação, arrastando do botão Adicionar ao Livro, da página LivroAutor, para a página criada (AutoresPublicados). A Listagem 13 exibe a navegação em detalhe no formato XML. Listagem 13. Navegação da página LivroAutor para AutoresPublicados ... <managed-bean> <managed-bean-name>admin$LivroAutor</managed-bean-name> <managed-bean-class>br.com.integrator.admin.LivroAutor</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <navigation-rule> <from-view-id>/admin/LivroAutor.jsp</from-view-id> <navigation-case> <from-outcome>publicado</from-outcome> <to-view-id>/admin/AutoresPublicados.jsp</to-view-id> </navigation-case> <navigation-case> </navigation-rule> ...

Page 115: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

115115

Alterando o menu Adicione mais três links: Cadastrar Editoras, Publicações e Autores Publicados.

Figura 20 – Menu da área administrativa do site Altere a propriedade id de cada um conforme deseja e altere para a string de retorno conforme mostrado em “Criando o relacionamento entre as páginas”.

Criando o relacionamento entre as páginas Devido a inúmeros relacionamentos, neste estudo de caso, o arquivo faces-config.xml foi colocado na íntegra (Listagem 13), em seu formato original, XML, para que você possa acompanhar cada relação, caso tenha impresso este capítulo. É recomendável olhar o código fonte do projeto, contido também no CD-ROM, para melhor compreensão. Listagem 13. Arquivo faces-config.xml <faces-config ... <managed-bean> <managed-bean-name>SessionBean1</managed-bean-name> <managed-bean-class>br.com.integrator.SessionBean1</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>Page1</managed-bean-name> <managed-bean-class>br.com.integrator.Page1</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>ApplicationBean1</managed-bean-name> <managed-bean-class>br.com.integrator.ApplicationBean1</managed-bean-class> <managed-bean-scope>application</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>RequestBean1</managed-bean-name> <managed-bean-class>br.com.integrator.RequestBean1</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>menu</managed-bean-name> <managed-bean-class>br.com.integrator.menu</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>admin$Livro</managed-bean-name> <managed-bean-class>br.com.integrator.admin.Livro</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>Livros</managed-bean-name> <managed-bean-class>br.com.integrator.Livros</managed-bean-class>

Page 116: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

116116

<managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>Contato</managed-bean-name> <managed-bean-class>br.com.integrator.Contato</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <navigation-rule> <from-view-id>/*</from-view-id> <navigation-case> <from-outcome>pesquisar</from-outcome> <to-view-id>/Pesquisado.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/Page1.jsp</from-view-id> <navigation-case> <from-outcome>contato</from-outcome> <to-view-id>/Contato.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>livros</from-outcome> <to-view-id>/Livros.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>autores</from-outcome> <to-view-id>/Autores.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>admin</from-outcome> <to-view-id>/Admin.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/Livros.jsp</from-view-id> <navigation-case> <from-outcome>contato</from-outcome> <to-view-id>/Contato.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>autores</from-outcome> <to-view-id>/Autores.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>admin</from-outcome> <to-view-id>/Admin.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/Contato.jsp</from-view-id> <navigation-case> <from-outcome>livros</from-outcome> <to-view-id>/Livros.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>autores</from-outcome> <to-view-id>/Autores.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>admin</from-outcome> <to-view-id>/Admin.jsp</to-view-id> </navigation-case> </navigation-rule> <managed-bean> <managed-bean-name>Autores</managed-bean-name> <managed-bean-class>br.com.integrator.Autores</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>admin$menu</managed-bean-name> <managed-bean-class>br.com.integrator.admin.menu</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>admin$Autor</managed-bean-name> <managed-bean-class>br.com.integrator.admin.Autor</managed-bean-class>

Page 117: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

117117

<managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>Admin</managed-bean-name> <managed-bean-class>br.com.integrator.Admin</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <navigation-rule> <from-view-id>/Admin.jsp</from-view-id> <navigation-case> <from-outcome>livros</from-outcome> <to-view-id>/Livros.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>autores</from-outcome> <to-view-id>/Autores.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>contato</from-outcome> <to-view-id>/Contato.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>logado</from-outcome> <to-view-id>/admin/Livro.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/admin/Autor.jsp</from-view-id> <navigation-case> <from-outcome>logout</from-outcome> <to-view-id>/Admin.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>cadlivro</from-outcome> <to-view-id>/admin/Livro.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>caded</from-outcome> <to-view-id>/admin/Editora.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>autpub</from-outcome> <to-view-id>/admin/AutoresPublicados.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>pubs</from-outcome> <to-view-id>/admin/Publicados.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/admin/Livro.jsp</from-view-id> <navigation-case> <from-outcome>cadautor</from-outcome> <to-view-id>/admin/Autor.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>logout</from-outcome> <to-view-id>/Admin.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>caded</from-outcome> <to-view-id>/admin/Editora.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>pubs</from-outcome> <to-view-id>/admin/Publicados.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>autpub</from-outcome> <to-view-id>/admin/AutoresPublicados.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>adlivroautor</from-outcome> <to-view-id>/admin/LivroAutor.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule>

Page 118: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

118118

<from-view-id>/Autores.jsp</from-view-id> <navigation-case> <from-outcome>admin</from-outcome> <to-view-id>/Admin.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>livros</from-outcome> <to-view-id>/Livros.jsp</to-view-id> </navigation-case> </navigation-rule> <application> <message-bundle>br.com.integrator.Bundle</message-bundle> </application> <managed-bean> <managed-bean-name>Pesquisado</managed-bean-name> <managed-bean-class>br.com.integrator.Pesquisado</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <navigation-rule> <from-view-id>/Pesquisado.jsp</from-view-id> <navigation-case> <from-outcome>livros</from-outcome> <to-view-id>/Livros.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>autores</from-outcome> <to-view-id>/Autores.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>admin</from-outcome> <to-view-id>/Admin.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>contato</from-outcome> <to-view-id>/Contato.jsp</to-view-id> </navigation-case> </navigation-rule> <managed-bean> <managed-bean-name>Busca</managed-bean-name> <managed-bean-class>br.com.integrator.Busca</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>topo</managed-bean-name> <managed-bean-class>br.com.integrator.topo</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>admin$Editora</managed-bean-name> <managed-bean-class>br.com.integrator.admin.Editora</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <navigation-rule> <from-view-id>/admin/Editora.jsp</from-view-id> <navigation-case> <from-outcome>cadlivro</from-outcome> <to-view-id>/admin/Livro.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>logout</from-outcome> <to-view-id>/Admin.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>cadautor</from-outcome> <to-view-id>/admin/Autor.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>pubs</from-outcome> <to-view-id>/admin/Publicados.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>autpub</from-outcome> <to-view-id>/admin/AutoresPublicados.jsp</to-view-id> </navigation-case> </navigation-rule> <managed-bean>

Page 119: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

119119

<managed-bean-name>admin$Publicar</managed-bean-name> <managed-bean-class>br.com.integrator.admin.Publicar</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> <managed-property> <property-name>livid</property-name> <value>#{param.livid}</value> </managed-property> </managed-bean> <managed-bean> <managed-bean-name>admin$Publicados</managed-bean-name> <managed-bean-class>br.com.integrator.admin.Publicados</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <navigation-rule> <from-view-id>/admin/Publicar.jsp</from-view-id> <navigation-case> <from-outcome>publicado</from-outcome> <to-view-id>/admin/Publicados.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>cadlivro</from-outcome> <to-view-id>/admin/Livro.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>cadautor</from-outcome> <to-view-id>/admin/Autor.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>logout</from-outcome> <to-view-id>/Admin.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>caded</from-outcome> <to-view-id>/admin/Editora.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>pubs</from-outcome> <to-view-id>/admin/Publicados.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>autpub</from-outcome> <to-view-id>/admin/AutoresPublicados.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/admin/Publicados.jsp</from-view-id> <navigation-case> <from-outcome>cadlivro</from-outcome> <to-view-id>/admin/Livro.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>logout</from-outcome> <to-view-id>/Admin.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>cadautor</from-outcome> <to-view-id>/admin/Autor.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>caded</from-outcome> <to-view-id>/admin/Editora.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>autpub</from-outcome> <to-view-id>/admin/AutoresPublicados.jsp</to-view-id> </navigation-case> </navigation-rule> <managed-bean> <managed-bean-name>admin$LivroAutor</managed-bean-name> <managed-bean-class>br.com.integrator.admin.LivroAutor</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <navigation-rule> <from-view-id>/admin/LivroAutor.jsp</from-view-id> <navigation-case> <from-outcome>publicado</from-outcome> <to-view-id>/admin/AutoresPublicados.jsp</to-view-id>

Page 120: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

120120

</navigation-case> <navigation-case> <from-outcome>cadlivro</from-outcome> <to-view-id>/admin/Livro.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>logout</from-outcome> <to-view-id>/Admin.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>cadautor</from-outcome> <to-view-id>/admin/Autor.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>caded</from-outcome> <to-view-id>/admin/Editora.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>pubs</from-outcome> <to-view-id>/admin/Publicados.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>autpub</from-outcome> <to-view-id>/admin/AutoresPublicados.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/admin/AutoresPublicados.jsp</from-view-id> <navigation-case> <from-outcome>cadlivro</from-outcome> <to-view-id>/admin/Livro.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>logout</from-outcome> <to-view-id>/Admin.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>cadautor</from-outcome> <to-view-id>/admin/Autor.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>caded</from-outcome> <to-view-id>/admin/Editora.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>pubs</from-outcome> <to-view-id>/admin/Publicados.jsp</to-view-id> </navigation-case> </navigation-rule> <managed-bean> <managed-bean-name>admin$AutoresPublicados</managed-bean-name> <managed-bean-class>br.com.integrator.admin.AutoresPublicados</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> ...

Page 121: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

121121

Capítulo Extra 6 

Estudo de caso completo com Visual Web JSF, Spring e Hibernate utilizando JPA  Este capítulo extra é uma versão do sistema criado nos Capítulos 7, 8 e estendidos no Capítulo Extra 5, só que criado utilizando Spring 2.5, Hibernate 3.2 e JPA (Java Persistence API), onde muitas explicações técnicas se encontram no Capítulo 10.

As características da aplicação O sistema segue o roteiro proposto pelo mesmo exemplo tido ao longo dos Capítulos 7, 8 e Extra 5, portanto, o design das páginas serão omitidos, sempre referindo a estes capítulos quando se tratar deste assunto. Neste capítulo será apresentado:

• A criação das entidades (POJOs); • O trabalho com relacionamentos da JPA (One-To-Many, Many-To-One e Many-To-Many); • A facilidade incorporada pelo Spring Framework; • A facilitação do DAO Genérico criado para gerar o sistema; • Utilização do pool C3P0 e cache de segundo nível com EhCache.

Ao final deste capítulo, o leitor terá habilidade de trabalhar em sistemas complexos e completos utilizando as tecnologias relacionadas, incluindo o seu teor técnico para maiores detalhes.

O Projeto Crie um novo projeto Web Java e chame-o de DesComVWSpringJPAHibernate. Selecione o framework Visual Web JSF e altere seu pacote para br.com.integrator. Após a criação do projeto, adicione o suporte ao Spring Framework através do direito do mouse sobre Libraries, em Add Library>spring-framework-2.5>Add Library. O plugin que fora instalado possui as bibliotecas do Hibernate e do Spring, como já visto no Capítulo 10. Atenção: Caso não tenha passado pelo livro, algumas bibliotecas podem estar faltando, portanto, confira os detalhes no capítulo 10 do seu livro.

As entidades e seus relacionamentos Como dito no Capítulo Extra 5, no decorrer do livro, duas tabelas foram utilizadas para o desenvolvimento da aplicação com Visual Web JSF. Agora, será necessário criar três novas tabelas, totalizando cinco: livros, autores, editoras, publicacao e livro_autor. As tabelas são ilustradas na Figura 1.

Page 122: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

122122

Figura 1 – Modelo de dados do projeto A Listagem 1, do Capítulo Extra 5, mostra o script para a criação das tabelas que serão

adicionadas.

As entidades POJO Na Figura 2, observa-se o mapeamento de quatro objetos que relacionam-se as cinco tabelas encontradas no banco de dados. Para criá-las pelo NetBeans, siga os passos demonstrados no quadro “Criando Entidades Persistentes no NetBeans”.

Figura 2 – Objetos a serem persistidos gerado por engenharia reversa do NetBeans IDE 6

Page 123: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

123123

Criando entidades persistentes no NetBeans

Siga estes passos para criar as entidades persistentes em seu projeto, para ficar em conformidade com o visto na Figura 2:

1. Com o direito do mouse sobre o projeto, selecione New>Entity Classes from Database; 2. Na caixa de diálogo New Entity Classes from Database selecione crie um DataSource

como já fora feito no Capítulo 10, em “Criando a Entidade Autor”; 3. Selecione todas as tabelas do banco de dados livraria na segunda etapa e avance (veja

Figura 3); 4. Na terceira etapa, altere o nome das classes em Class Name para o singular, seguindo o

padrão de desenvolvimento. Altere o pacote digitando br.com.integrator.entities; 5. Clique no botão Create Persistence Unit e mantenha o Hibernate, dando um nome de

livraria na Persistence Unit. Confirme tudo.

Figura 3 – Selecionando as tabelas para criar as entidades persistentes

Page 124: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

124124

Figura 4 – Criação das entidades e seu pacote Atenção: Procure não se confundir neste capítulo. Se estiver falando do Capítulo 10, significa que a explicação está neste lugar. O mesmo vale para o Capítulo 8 e Extra 5. Este capítulo é uma mistura de ambos, onde no 8 e Extra 5 temos o layout proposto e no 10 a integração com Spring, Hibernate e JPA.

Alterando as entidades Embora o trabalho mais difícil seja feito pelo NetBeans IDE, altere as entidades criadas para como mostrado nas Listagens de 1 a 5, a seguir, onde serão omitidos as anotações @NamedQueries e os métodos getters e setters: Listagem 1. O código da entidade Usuario @Entity @Table(name = "usuarios") public class Usuario implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "id", nullable = false) private Integer id; @Column(name = "usuario") private String usuario; @Column(name = "senha") private String senha; //getters e setters omitidos

Page 125: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

125125

Listagem 2. O código da entidade Livro @Entity @Table(name = "livros") public class Livro implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false) private Integer id; @Column(name = "titulo") private String titulo; @Column(name = "edicao") private Integer edicao; @Column(name = "publicacao") private Integer publicacao; @Column(name = "descricao") private String descricao; @Column(name = "imagem") private String imagem; @OneToMany(mappedBy = "livro", fetch = FetchType.LAZY) private Collection<Publicacao> publicacoes; @ManyToMany(fetch=FetchType.LAZY, mappedBy = "livros") private Set<Autor> autores; //getters e setters omitidos Listagem 3. O código da entidade Autor @Entity @Table(name = "autores") public class Autor implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false) private Integer id; @Column(name = "nome") private String nome; @Column(name = "email") private String email; @Column(name = "nascimento") @Temporal(TemporalType.DATE) private Date nascimento; @ManyToMany(cascade={CascadeType.MERGE,CascadeType.PERSIST}) @JoinTable(name="livro_autor", joinColumns=@JoinColumn(name="autor_id"), inverseJoinColumns=@JoinColumn(name="livro_id")) private Set<Livro> livros; //getters e setters omitidos

Page 126: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

126126

Listagem 4. O código da entidade Editora @Entity @Table(name = "editoras") public class Editora implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false) private Integer id; @Column(name = "editora") private String editora; @OneToMany(mappedBy = "editora", fetch = FetchType.LAZY) private Collection<Publicacao> publicacoes; //getters e setters omitidos Listagem 5. O código da entidade Publicacao @Entity @Table(name = "publicacao") public class Publicacao implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false) private Integer id; @JoinColumn(name = "editora_id", referencedColumnName = "id") @ManyToOne(fetch = FetchType.EAGER) private Editora editora; @JoinColumn(name = "livro_id", referencedColumnName = "id") @ManyToOne(fetch = FetchType.EAGER) private Livro livro; //getters e setters omitidos

Mapeamento objetos simples O mapeamento mais simples, onde um objeto tem apenas tipos de dados básicos, que se entende por tipos básicos aqueles que possuem um correspondente na SQL, ou seja, o tipo String em Java é considerado os de campos de texto em seu correspondente SQL.

Mapeamento de objetos com coleção de objetos Esse mapeamento é usado quando um objeto possui um conjunto de outros objetos. Para entendê-lo, observe que temos na entidade Livro, uma coleção de publicacoes, por exemplo, que armazenará o conjunto de publicações. Em sua classe relacionada, através da entidade Publicacao, temos o atributo livro, que simplesmente relaciona um livro a sua publicação, enquanto que publicacoes, de Livro, referencia a classe Publicacao. Isso indica que podemos ter muitas publicações de um determinado livro. Ou melhor explicando, cada livro lançado pode ter sua determinada publicação e sua exclusão não afeta ao fato de existir um livro. Estes relacionamentos são:

Page 127: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

127127

• One-To-Many (Um-Para-Muitos) – relacionamento da tabela livros (entidade Livro) para a tabela publicacoes (entidade Publicacao). Para este relacionamento utilizamos a anotação @OneToMany;

• Many-To-One (Muitos-Para-Um) – o inverso do relacionamento Um-Para-Muitos. Para este relacionamento utilizamos a anotação @ManyToOne;

A classe Livro, no exemplo, é a que possui um mapeamento do tipo Um-Para-Muitos (1-n), através do atributo de coleção publicacoes. O seu mapeamento foi feito na Listagem 2 a partir da anotação @OneToMany. Como a coleção conterá objetos do tipo Publicacao, então está classe também deverá ser uma classe persistente da aplicação - observe que utilizamos generics para o tipo. Na anotação @OneToMany, existe um atributo denominado mappedBy que deverá receber como valor o nome do atributo encontrado na classe Publicacao (classe dos tipos de objetos da coleção). Ou seja, a tabela publicacao possui uma chave estrangeira (livro_id) para a tabela livros, que é representada pelo atributo de classe livro da entidade Publicacao, utilizado pelo atributo mappedBy da anotação @OneToMany, ou seja, mappedBy=“livro”. Já o atributo fetch indica quando o conteúdo do atributo será trazido da base de dados. Este por sua vez, possui dois valores:

• FetchType.EAGER: este valor indica que, se o objeto "pai" for trazido da base de dados, o atributo mapeado com fetch=FetchType.EAGER fará com que o seu conteúdo também seja trazido;

• FetchType.LAZY: este atributo indica que, se o objeto "pai" for trazido da base de dados, o atributo mapeado com fetch=FetchType.LAZY fará com que o seu conteúdo somente seja trazido quando acessado pela primeira vez.

Quando um relacionamento utiliza FetchType.LAZY, a consulta retorna apenas os dados referentes a livros, de forma que se fossem necessários os dados da coleção publicacoes, bastaria acessar o atributo que a representa no objeto Livro. A anotação @ManyToOne também possui o atributo fetch, que possui o mesmo comportamento de @OneToMany. Com a anotação @JoinColumn informamos qual o nome da coluna que corresponde à chave estrangeira do mapeamento, o que no caso deste exemplo, seria name=“livro_id”. O atributo referencedColumnName indica a coluna referenciada na tabela “pai” do banco de dados, que no caso em livros, seria o campo id. Já para o caso da tabela livro_autor, há um relacionamento Muitos-Para-Muitos. As das entidades Livro e Autor, ilustradas nas Listagens 2 e 3, respectivamente, possuem mapeamentos de coleções com o relacionamento Muitos-Para-Muitos (n-n), que é feito a partir da anotação @ManyToMany. O uso da anotação @JoinTable também se faz necessário para informar o nome da tabela intermediária entre as entidades. Esta anotação possui o atributo name que informa o nome da tabela intermediária que representa o mapeamento Muitos-Para-Muitos, no caso, a tabela livro_autor. O atributo joinColumns recebe como valor uma anotação @JoinColumn, informando o nome da coluna na tabela intermediária, que representa a classe onde está o mapeamento Muitos-Para-Muitos. No atributo inverseJoinColumns é informado qual a coluna que representa a outra entidade no relacionamento. Na entidade Livro, para não haver a repetição das anotações utilizadas em Autor, basta adicionar o atributo mappedBy em @ManyToMany, ficando mappedBy= “livros”. Isso indica que na classe Autor há um atributo chamado livros que contém a informação mapeada. Esta condição também indica que Livro seria o lado “fraco” do relacionamento. O uso de Set para o tipo dos atributos livros e autores é para que não haja repetições. Nossa intenção é trabalhar da seguinte forma:

Page 128: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

128128

Você pode ter muitos autores para um livro, na tabela livro_autor, mas só terá um livro para cada autor, em outras palavras, um livro pode ter sido escrito por muitos autores, mas estes não se repetem para cada livro, como: Edson Gonçalves, Edson Gonçalves escreveu Desenvolvendo aplicações Web com NetBeans 6, ou seja, houve uma repetição desnecessária de dados que o Hibernate ignorará.

Utilizando o DAO genérico para criar outros No Capítulo 10 do livro, temos um DAO genérico que facilita o desenvolvimento de outros sem esforço adicional e repetição de código. Tanto a interface BaseDao como a classe que a implementa, BaseDaoImp, terão um método adicional, como mostrado nas Listagens 6 e 7. Listagem 6. A interface BaseDao alterada ... public interface BaseDao<T, ID> { //..omitido por não haver alteração public abstract Query pesq(String query); } Listagem 7. A classe BaseDaoImp alterada ... public class BaseDaoImp<T, ID> implements BaseDao<T, ID> { //..omitido por não haver alteração public Query pesq(String query) { return getEntityManager().createQuery(query); } } Este método adicionado permitirá a execução de queries personalizadas, para os casos em que iremos utilizar mais de uma entidade.

Os DAOs Como definido no Capítulo 10 do livro, temos que criar os DAOs para trabalhar com as entidades desenvolvidas, estendendo a base. As Listagens de 8 a 17 mostram os DAOs que serão usados neste capítulo. Listagem 8. A interface EditoraDao package br.com.integrator.dao; import br.com.integrator.entities.Editora; public interface EditoraDao extends BaseDao<Editora, Integer>{ } Listagem 9. A classe EditoraDaoImp package br.com.integrator.dao; import br.com.integrator.entities.Editora; public class EditoraDaoImp extends BaseDaoImp<Editora, Integer> implements EditoraDao { }

Page 129: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

129129

Listagem 10. A interface LivroDao package br.com.integrator.dao; import br.com.integrator.entities.Livro; public interface LivroDao extends BaseDao<Livro, Integer>{ } Listagem 11. A classe LivroDaoImp package br.com.integrator.dao; import br.com.integrator.entities.Livro; public class LivroDaoImp extends BaseDaoImp<Livro, Integer> implements LivroDao { } Listagem 12. A interface PublicacaoDao package br.com.integrator.dao; import br.com.integrator.entities.Publicacao; public interface PublicacaoDao extends BaseDao<Publicacao, Integer>{ } Listagem 13. A classe PublicacaoDaoImp package br.com.integrator.dao; import br.com.integrator.entities.Publicacao; public class PublicacaoDaoImp extends BaseDaoImp<Publicacao, Integer> implements PublicacaoDao { } Listagem 14. A interface UsuarioDao package br.com.integrator.dao; import br.com.integrator.entities.Usuario; public interface UsuarioDao extends BaseDao<Usuario, Integer>{ } Listagem 15. A classe UsuarioDaoImp package br.com.integrator.dao; import br.com.integrator.entities.Usuario; public class UsuarioDaoImp extends BaseDaoImp<Usuario, Integer> implements UsuarioDao { } Listagem 16. A classe AutorDao package br.com.integrator.dao; import br.com.integrator.entities.Autor;

Page 130: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

130130

public interface AutorDao extends BaseDao<Autor, Integer>{ } Listagem 17. A classe AutorDaoImp package br.com.integrator.dao; import br.com.integrator.entities.Autor; public class AutorDaoImp extends BaseDaoImp<Autor, Integer> implements AutorDao { }

Configurando o Spring Com a criação dos DAOs, o Spring precisará ser configurado para que o acesso a dados se apóie nos recursos do framework. Com o direito sobre WEB-INF, em Projects, vá em New>Other. Na caixa de diálogo, vá em Spring Framework e selecione Spring Beans Context file. Na segunda etapa, altere para applicationContext em File Name. Na terceira etapa do assistente, selecione o Namespace exibido na Figura 5 e confirme.

Figura 5 – Seleção do namespace do arquivo de configuração do Spring Framework. O assistente adicionará automaticamente o Namespace utilizado pelo Spring em seu arquivo de configuração. Resta configurar os beans que serão utilizados para que o Spring possa gerir as transações e informá-lo da classe que será usada para a injeção de dependências. Para a execução em ambientes Java EE, utilizamos a factory org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean: <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="livraria" /> </bean>

Page 131: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

131131

Com a propriedade de LocalContainerEntityManagerFactoryBean especificamos o nome da persistence unit do arquivo persistence.xml. Veja outros detalhes no Capítulo 10. JpaTransactionManager precisa de qualquer implementação de javax.persistence.EntityManagerFactory para colaborar com EntityManager produzido pela fabrica, para conduzir transações. O JpaTransactionManager é recomendado para aplicações que utilizam apenas uma EntityManager. Para que não tenhamos que fazer injeção de dependência do EntityManager em todos os nossos DAOs, utilizamos a classe org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor, que procura todas as classes anotadas com @PersistenceContext e faz a injeção de dependência automaticamente: <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

A Listagem 18 exibe o arquivo de configuração do Spring que será utilizado pela aplicação. Listagem 18. Configuração do arquivo applicationContext.xml. <beans ... <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="livraria" /> </bean> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" /> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <tx:annotation-driven /> <bean id="autorDao" class="br.com.integrator.dao.AutorDaoImp" /> <bean id="editoraDao" class="br.com.integrator.dao.EditoraDaoImp" /> <bean id="usuarioDao" class="br.com.integrator.dao.UsuarioDaoImp" /> <bean id="publicacaoDao" class="br.com.integrator.dao.PublicacaoDaoImp" /> <bean id="livroDao" class="br.com.integrator.dao.LivroDaoImp" /> </beans> Para iniciar o Spring com a aplicação, o arquivo applicationContext.xml deverá ser registrado por um listener em web.xml: <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener>

Para trabalhar com a JPA, o Spring também fornece mais configurações. Ao trabalhar com relacionamentos para outras entidades, é importante entender que; como estamos trabalhando com o Hibernate, em alguns casos você utilizou a estratégia Lazy. Quando a aplicação termina de ler os dados desta estratégia, a sessão é fechada, lançando uma exceção do tipo LazyInitializationException. Isso significa que temos de deixar a sessão do Hibernate aberta ou inicializar todos os relacionamentos antes de renderizar a página. Evidentemente que, este tipo de situação por si só, causaria um problema de performance. Para evitá-la, no Hibernate, utilizamos um padrão chamado

Page 132: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

132132

de "Open Session in View". Quando um servidor web recebe uma requisição, esta é automaticamente filtrada pelo Interceptador/Filtro, podendo executar qualquer código antes e depois da mesma. Embora o exemplo deste artigo não trate de relacionamentos, muito menos sobre a estratégia Lazy, é importante comentar que, no uso de JPA, teríamos que criar um padrão semelhante para EntityManager2. O Spring possui um filtro que trabalha sobre este conceito, criando um padrão "Open EntityManager in View", que deve ser configurado em web.xml, conforme o trecho mostrado: <filter> <filter-name>openEntityManager</filter-name> <filter-class> org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter </filter-class> </filter> Para este capítulo, iremos utilizar o Filtro, como exemplo, onde na Listagem 19 é exibida toda a configuração que deve ser adicionada em web.xml.

Listagem 19. Configurando o Spring Framework em web.xml. <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext*.xml</param-value> </context-param> <filter> <filter-name>openEntityManager</filter-name> <filter-class> org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter </filter-class> </filter> <filter-mapping> <filter-name>openEntityManager</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

Criando um teste unitário Para verificar se está funcionando os DAOs criados, é uma boa prática desenvolver um teste sobre as classes criadas. No Capítulo 4 você viu como fazer um teste unitário para uma classe que utilizava acesso a dados via JDBC. Neste capítulo, será um exemplo de como fazer testes usando o Spring Framework. Para executar este teste, vamos utilizar os recursos do Spring Framework na versão 2.5. Mas para isso, teremos que adicionar duas bibliotecas JARs: junit-4.4.jar e spring-teste.jar. Ambos os arquivos existem no download da biblioteca Spring com suas dependências.

2 A interface EntityManager é responsável pelas operações de persistência no EJB 3.0 e gerência de entidades persistentes (Entidades).

Page 133: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

133133

Clique com o direito sobre Test Libraries, em seu projeto, e selecione no menu de contexto o item Add JAR/Folder. Selecione as duas bibliotecas citadas e confirme. Veja onde elas ficarão, na Figura 6.

Figura 6 – Adição das bibliotecas em Test Libraries Listagem 20. Teste unitário usando o Spring Framework package br.com.integrator.test; import br.com.integrator.dao.UsuarioDao; import br.com.integrator.entities.Usuario; import java.util.List; import org.junit.Test; import static org.junit.Assert.*; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:**/applicationContext*.xml"}) public class UsuarioDAOTest { private UsuarioDao usuarioDao; @Autowired public void setUsuarioDao(UsuarioDao usuarioDao) { this.usuarioDao = usuarioDao; } @Test public void addUsuario(){ Usuario usuario = new Usuario(); usuario.setId(1); usuario.setUsuario("integrator"); usuario.setSenha("integrator"); usuarioDao.save(usuario); List<Usuario> users = usuarioDao.getAll("SELECT u FROM Usuario u"); assertEquals(1, users.size()); }

Page 134: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

134134

@Test public void atuUsuario(){ Usuario usuario = usuarioDao.getById(1); usuario.setUsuario("edson"); usuarioDao.update(usuario); List<Usuario> users = usuarioDao.getAll("SELECT u FROM Usuario u"); assertEquals("edson", users.get(0).getUsuario()); } @Test public void excUsuario(){ Usuario usuario = usuarioDao.getById(1); usuarioDao.delete(usuario); List<Usuario> users = usuarioDao.getAll("SELECT u FROM Usuario u"); assertEquals(0, users.size()); } } A Listagem 20 exibe um teste unitário utilizando as anotações do Spring Framework. Embora o NetBeans possua uma biblioteca JUnit em seu programa, infelizmente, para usar a anotação @RunWith, foi preciso adicionar a biblioteca compatível com a versão atual, no momento em que este livro é escrito, do Spring. Com a anotação @ContextConfiguration você define o nome do arquivo de configuração da aplicação feito para o uso do Spring, definindo seu nome através do atributo locations (que aceita um array para mais arquivos). Com a anotação @Autowired você tem a injeção do Spring e pode então criar seus testes unitários. Os detalhes dos métodos que podemos usar para testes podem ser vistos no Capítulo 4.

Figura 7 – Resultados do teste unitário Você pode fazer outros testes com os demais DAOs criados.

Controlando o acesso Temos para o caso, diversos Facades que serão usados para controlar os DAOs criados e integrá-los a sua aplicação Visual Web JSF. As Listagens a seguir mostram as classes responsáveis pela lógica de negócios, delegando chamadas à camada de acesso a dados e controle transacional. Este controle de transações será administrado pelo Spring, através da injeção nos atributos que já foram configurados no arquivo applicationContext.xml:

Page 135: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

135135

<bean id="autorDao" ... <bean id="editoraDao" ... <bean id="usuarioDao" ... <bean id="publicacaoDao" ... <bean id="livroDao" ... Estas classes terão depois a injeção do Spring no managed bean para trabalhar com o JavaServer Faces. Para trabalhar com a entidade Autor, recorra ao livro, que já possui o Facade AutorController, ao qual aqui serão apenas apresentados os métodos adicionais a classe. Listagem 21. Métodos adicionais da classe AutorController //...omitido por não haver mudanças public Autor pesquisarAutor(Long id) { return autorDao.getById(id); } public List todosAutorLivro() { return autorDao.pesq("SELECT a.id, a.nome, l.titulo " + "FROM Autor a JOIN a.livros l").getResultList(); } Listagem 22. O código da classe UsuarioController package br.com.integrator.controller; import java.util.List; import br.com.integrator.dao.BaseDao; import br.com.integrator.entities.Usuario; import javax.persistence.Query; public class UsuarioController { /** * Injetado pelo Spring * @param usuarioDao */ private BaseDao<Usuario, Integer> usuarioDao; public BaseDao<Usuario, Integer> getUsuarioDao() { return usuarioDao; } public void setUsuarioDao(BaseDao<Usuario, Integer> UsuarioDao) { this.usuarioDao = UsuarioDao; } public void atualizar(Usuario Usuario) { usuarioDao.update(Usuario); } public void salvar(Usuario Usuario) { usuarioDao.save(Usuario); } public void excluir(Usuario Usuario) { usuarioDao.delete(Usuario); } public List todos() { return usuarioDao.getAll("SELECT u FROM Usuario u"); } public Usuario pesquisar(String usuario){ Query q = usuarioDao.pesq("SELECT u FROM Usuario u WHERE u.usuario=?1"); return (Usuario) q.setParameter(1, usuario).getSingleResult(); } }

Page 136: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

136136

Listagem 23. O código da classe EditoraController package br.com.integrator.controller; import java.util.List; import br.com.integrator.dao.BaseDao; import br.com.integrator.entities.Editora; public class EditoraController { /** * Injetado pelo Spring * @param editoraDao */ private BaseDao<Editora, Integer> editoraDao; public BaseDao<Editora, Integer> getEditoraDao() { return editoraDao; } public void setEditoraDao(BaseDao<Editora, Integer> EditoraDao) { this.editoraDao = EditoraDao; } public void atualizar(Editora Editora) { editoraDao.update(Editora); } public void salvar(Editora Editora) { editoraDao.save(Editora); } public void excluir(Editora Editora) { editoraDao.delete(Editora); } public List todos() { return editoraDao.getAll("SELECT e FROM Editora e"); } } Listagem 24. O código da classe LivroController package br.com.integrator.controller; import java.util.List; import br.com.integrator.dao.BaseDao; import br.com.integrator.entities.Livro; import javax.persistence.Query; public class LivroController { /** * Injetado pelo Spring * @param livroDao */ private BaseDao<Livro, Integer> livroDao; public BaseDao<Livro, Integer> getLivroDao() { return livroDao; } public void setLivroDao(BaseDao<Livro, Integer> LivroDao) { this.livroDao = LivroDao; } public void atualizar(Livro Livro) { livroDao.update(Livro); } public void salvar(Livro Livro) { livroDao.save(Livro); } public void excluir(Livro Livro) {

Page 137: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

137137

livroDao.delete(Livro); } public List todos() { return livroDao.getAll("SELECT l FROM Livro l"); } public List<Livro> pesquisar(String titulo){ Query q = livroDao.pesq("SELECT l FROM Livro l WHERE l.titulo LIKE ?1"); return q.setParameter(1, "%"+titulo+"%").getResultList(); } public Livro pesquisarLivro(Integer id) { return livroDao.getById(id); } } Listagem 25. O código da classe PublicacaoController package br.com.integrator.controller; import java.util.List; import br.com.integrator.dao.BaseDao; import br.com.integrator.entities.Publicacao; public class PublicacaoController { /** * Injetado pelo Spring * @param publicacaoDao */ private BaseDao<Publicacao, Integer> publicacaoDao; public BaseDao<Publicacao, Integer> getPublicacaoDao() { return publicacaoDao; } public void setPublicacaoDao(BaseDao<Publicacao, Integer> PublicacaoDao) { this.publicacaoDao = PublicacaoDao; } public void atualizar(Publicacao Publicacao) { publicacaoDao.update(Publicacao); } public void salvar(Publicacao Publicacao) { publicacaoDao.save(Publicacao); } public void excluir(Publicacao Publicacao) { publicacaoDao.delete(Publicacao); } public List todasPublicacoes() { return publicacaoDao.pesq("SELECT p.id, l.titulo, e.editora FROM " + "Publicacao p JOIN p.editora e " + "JOIN p.livro l").getResultList(); } public List todosLivroAutorPub() { return publicacaoDao.pesq("SELECT p.id, l.titulo, e.editora, a.nome FROM " + "Publicacao p JOIN p.editora e " + "JOIN p.livro l JOIN l.autores a").getResultList(); } } Estas classes dispensam apresentação, uma vez que trabalham com seus respectivos DAOs para criar os CRUDs.

Page 138: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

138138

Integrando o Visual Web JSF ao Spring Para configurar o Spring de modo que ele possibilite se integrar ao JavaServer Faces, é necessário adicionar o elemento variable-resolver, no arquivo faces-config.xml, como fora feito no Capítulo 10 o livro, para chamar a classe DelegatingVariableResolver do framework: <application> <variable-resolver> org.springframework.web.jsf.DelegatingVariableResolver </variable-resolver> </application> A classe DelegatingVariableResolver é capaz de resolver beans declarados no Spring e injetá-los no managed bean de forma transparente. Esta injeção é indicada com a sintaxe #{bean nomeado no Spring}, a mesma utilizada pelo JSF para injetar dependências nos managed beans. Isso indica que nosso managed bean deixa de ser responsável por instanciar o objeto que irá utilizar e passa a recebê-lo do Spring. A Listagem 26 mostra os managed beans configurados em faces-config.xml. Listagem 26. Alterações no arquivo faces-config.xml //...omitido por não haver alterações <application> <variable-resolver> org.springframework.web.jsf.DelegatingVariableResolver </variable-resolver> </application> <managed-bean> <managed-bean-name>UsuarioController</managed-bean-name> <managed-bean-class> br.com.integrator.controller.UsuarioController </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>usuarioDao</property-name> <value>#{usuarioDao}</value> </managed-property> </managed-bean> <managed-bean> <managed-bean-name>LivroController</managed-bean-name> <managed-bean-class> br.com.integrator.controller.LivroController </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>livroDao</property-name> <value>#{livroDao}</value> </managed-property> </managed-bean> <managed-bean> <managed-bean-name>EditoraController</managed-bean-name> <managed-bean-class> br.com.integrator.controller.EditoraController </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>editoraDao</property-name> <value>#{editoraDao}</value> </managed-property> </managed-bean> <managed-bean> <managed-bean-name>AutorController</managed-bean-name> <managed-bean-class> br.com.integrator.controller.AutorController </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>autorDao</property-name>

Page 139: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

139139

<value>#{autorDao}</value> </managed-property> </managed-bean> <managed-bean> <managed-bean-name>PublicacaoController</managed-bean-name> <managed-bean-class> br.com.integrator.controller.PublicacaoController </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>publicacaoDao</property-name> <value>#{publicacaoDao}</value> </managed-property> </managed-bean> ... Atenção: Para detalhes quanto ao comportamento mostrado aqui, veja o Capítulo 10.

Acessando o Facade pelo Visual Web JSF Para acessarmos as classes Facade criadas, e seus métodos através do Design do Visual Web JSF, será necessário configurar a classe SessionBean1, o padrão do Visual Web JSF é trafegar em um escopo de sessão. Listagem 27. Alterações na classe SessionBean1 //...omitido por não haver alterações por enquanto protected LivroController getLivroController() { return (LivroController) getBean("LivroController"); } protected EditoraController getEditoraController() { return (EditoraController) getBean("EditoraController"); } protected AutorController getAutorController() { return (AutorController) getBean("AutorController"); } protected PublicacaoController getPublicacaoController() { return (PublicacaoController) getBean("PublicacaoController"); } //transporta em sessão um inteiro selecionado private Integer id = null; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } private Livro[] livros; public Livro[] getLivros() { return livros; } public void setLivros(Livro[] livros) { this.livros = livros; } //carrega todos os livros public void todosLivros() { livros = (Livro[]) getLivroController(). todos().toArray(new Livro[0]); } private Editora[] editoras;

Page 140: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

140140

public Editora[] getEditoras() { return editoras; } public void setEditoras(Editora[] editoras) { this.editoras = editoras; } //carrega todas as editoras public void todasEditoras() { editoras = (Editora[]) getEditoraController(). todos().toArray(new Editora[0]); } private Autor[] autores; public Autor[] getAutores() { return autores; } public void setAutores(Autor[] autores) { this.autores = autores; } //carrega todos os autores public void todosAutores() { autores = (Autor[]) getAutorController(). todos().toArray(new Autor[0]); } Atenção: Termine fazendo Build no projeto, como recomendado no Capítulo 10 (veja as explicações de como funciona no livro em caso de dúvida).

Os arquivos persistence.xml e log4j.properties Altere o arquivo persistence.xml e crie o log4j.properties como feito no livro, através do Capítulo 10.

As páginas da aplicação As páginas da aplicação seguirão o Layout (design, componentes, propriedades dos componentes) mostradas nas montagens decorridas dos Capítulos 7, 8 e Extra 5.

Montando sua aplicação para utilizar Spring e Hibernate com JPA Seguindo um roteiro apresentado pelo Capítulo 8, iremos gradualmente trabalhar com a aplicação Visual Web JSF integrada com Spring e Hibernate através da JPA (diferente do CRUD elaborado no Capítulo 10 sobre este mesmo assunto). Crie uma página Visual Web JSF chamada Livros, como feito no início do Capítulo 8 do livro.

Page 141: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

141141

Figura 8 – Tela inicial da página Livros Vá até Table Layout e altere em Get Data From para livros. Deixe os campos para serem exibidos e os configure como no Capítulo 8, conforme a Figura 9.

Figura 9 – Definição dos campos do componente Table Assim como apresentado no Capítulo 10, no desenvolvimento integrado com o Spring e JPA, o Visual Web JSF pega os valores do Array livros e possibilita manipulá-los visualmente.

Page 142: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

142142

Por fim, adicione no método prerender() a chamada ao método todosLivros() de SessionBean1: public void prerender() { getSessionBean1().todosLivros(); } Nota: Não se preocupe com a navegação de páginas, pois esta será feita de uma forma mais simples para este estudo de caso.

A criação do cadastro de livros Na área administrativa, como feito no Capítulo 8, temos o cadastro de livros, dentro do diretório admin. Para este caso, a primeira diferença apenas no arquivo estará no nome, que deverá ser Livros e não Livro como no primeiro exemplo. Isso é necessário para evitar problemas quanto à classe da página, que possui seu mesmo nome, ficando idêntica a entidade Livro. Veja a Figura 10 para maior esclarecimento.

Figura 10 – Layout da página Livros de admin Para este caso, será necessário criar apenas um formulário virtual para o link Editar. Os demais detalhes para a elaboração do design serão os mesmos. Para o componente Table será executado o mesmo passo que na elaboração da página para exibir os livros, com a diferença de acrescentarmos três links.

Page 143: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

143143

Detalhe da página Livros de admin Abra a página Livros.jsp, de admin, e adicione uma nova coluna ao componente Table da página. Esta nova coluna terá um Hyperlink como tipo de componente (Component Type). Em Header Text digite Publicação e em Value Expression digite Gerar. Selecione o link Gerar, e vá até suas propriedades. Dê um clique no botão de três pontos na propriedade url. Digite em URL, mantendo Use value, como mostrado a seguir: /admin/Publicar.faces?livid=#{currentRow.value['livros.id']}&titulo=#{currentRow.value['livros.titulo']} O que será transmitido via URL foi colorido da seguinte forma:

• Em vermelho – temos as variáveis que serão transmitidas; • Em azul – temos os valores destas variáveis, que correspondem a valores das colunas do

banco de dados; • Em verde – a concatenação para envio de mais de uma variável, o que ocorre no caso.

Nota: Caso precise de detalhes visuais para entender este trecho, olhe no Capítulo Extra 5.

Criando o CRUD com a página Como um CRUD já foi apresentado passo a passo no Capítulo 10, com suas devidas explicações, serão mostrados apenas os códigos de cada elemento a seguir. Listagem 28. Criação do método getLivroController() protected LivroController getLivroController() { return (LivroController) getBean("LivroController"); } Listagem 29. Alterações no método prerender() public void prerender() { //verifica se id não é nulo Integer id = getSessionBean1().getId(); if (id != null) { //capta os Livros Livro[] livros = getSessionBean1().getLivros(); //filtra somente o selecionado para edição Livro livro = livros[id]; //preenche os campos do formulário tftitulo.setText(livro.getTitulo()); tadescricao.setText(livro.getDescricao()); imagemLivro.setUrl("/images/" + livro.getImagem()); tfedicao.setText(livro.getEdicao()); tfpublicacao.setText(livro.getPublicacao()); } //chama o método todosLivros() para refletir na tabela getSessionBean1().todosLivros(); }

Page 144: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

144144

Listagem 30. Alterações no método do link Excluir public String excluir_action() { try { //captura a linha atual do link de exclusão clicado RowKey rowKey = tableRowGroup1.getRowKey(); if (rowKey != null) { Livro[] livros = getSessionBean1().getLivros(); Integer id = Integer.parseInt(rowKey.getRowId()); //seleciona somente o livro que será removido Livro livro = livros[id]; //chama o controller para excluir o livro selecionado getLivroController().excluir(livro); //limpa o ID de SessionBean1 caso esteja com valor getSessionBean1().setId(null); //limpa os campos existentes tftitulo.setText(null); tfedicao.setText(null); tfpublicacao.setText(null); tadescricao.setText(null); //informa ao administrador a exclusão info("Livro excluído!"); } } catch (Exception ex) { error("Erro encontrado: " + ex); } //retorna nulo pois não muda a página return null; } Listagem 31. Alterações no método do link Editar public String editar_action() { try { // captura a linha atual do componente Table TableRowDataProvider rowData = (TableRowDataProvider) getBean("currentRow"); //armazena o id do livro getSessionBean1().setId(Integer.parseInt(rowData.getTableRow().getRowId())); } catch (Exception ex) { error("Erro encontrado: " + ex); } return null; } Listagem 32. Alterações no método do botão Salvar public String btSalvar_action() { String imagem = null; //define o upload de arquivos através do componente File Upload UploadedFile uploadedFile = fimagem.getUploadedFile(); if (!uploadedFile.getOriginalName().equals("")) {

Page 145: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

145145

ServletContext theApplicationsServletContext = (ServletContext) this.getExternalContext().getContext(); //define o caminho físico do diretório images String path = theApplicationsServletContext.getRealPath("/images"); //captura o nome original do arquivo imagem = uploadedFile.getOriginalName(); //captura o tipo de arquivo String uploadedFileType = uploadedFile.getContentType(); //verifica se o arquivo é uma imagem válida if (uploadedFileType.equals("image/jpeg") || uploadedFileType.equals("image/pjpeg") || uploadedFileType.equals("image/gif")) { try { File file = new File(path + "/" + imagem); //escreve o arquivo no diretório determinado uploadedFile.write(file); } catch (Exception ex) { error("Problema com o arquivo: " + imagem); } } else { error("É aceito somente JPEG, PJPEG ou GIF."); } } try { String mensagem; Integer id = getSessionBean1().getId(); //se não houver algo em edição if (id == null) { Livro livro = new Livro(); //captura os valores de cada componente no formulário //e os atribui a seus determinados campos no banco de dados livro.setTitulo(tftitulo.getText().toString()); livro.setEdicao((Integer) tfedicao.getText()); livro.setPublicacao((Integer) tfpublicacao.getText()); livro.setDescricao(tadescricao.getText().toString()); livro.setImagem(imagem); getLivroController().salvar(livro); info("Salvo com sucesso!"); } else { Livro[] livros = getSessionBean1().getLivros(); //seleciona somente o livro que será editado Livro livro = livros[id]; //caso não haja novo upload da imagem //utiliza a antiga if (uploadedFile.getOriginalName().equals("")) { imagem = livro.getImagem(); } //captura os valores de cada componente no formulário //e os atribui a seus determinados campos no banco de dados livro.setTitulo(tftitulo.getText().toString()); livro.setEdicao((Integer) tfedicao.getText()); livro.setPublicacao((Integer) tfpublicacao.getText()); livro.setDescricao(tadescricao.getText().toString()); livro.setImagem(imagem); getLivroController().atualizar(livro); info("Atualizado com sucesso!");

Page 146: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

146146

} //limpa os campos existentes tftitulo.setText(null); tfedicao.setText(null); tfpublicacao.setText(null); tadescricao.setText(null); //torna nulo o valor de id getSessionBean1().setId(null); } catch (Exception ex) { //informa o erro caso ocorra ao administrador error("Não foi possível adicionar" + ex.getMessage()); } //retorna nulo pois não muda a página return null; }

As demais páginas administrativas de cadastro simples Agora você criará mais duas páginas para cadastros CRUD: Editoras e Autores. Ambos seguirão um layout similar ao da página de Livros, tirando o fato de não haver imagens e upload de arquivos.

Figura 11 – Página de cadastro de Autores

Page 147: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

147147

Para a página de cadastro de autores, você trabalhará com Autor e getAutores(). Para o cadastro de editoras, será Editora e getEditoras(). Em ambos os casos, serão necessários o uso de formulários virtuais para a chamada de edição de dados.

Figura 12 – Página de cadastro de Editoras Observação: Os códigos das páginas Editoras e Autores serão omitidos deste capítulo, uma vez que podem ser encontrados nos arquivos fontes do projeto no livro, incluso no CD-ROM, e por possuem semelhanças entre suas operações.

Acessando a área administrativa Como feito no Capítulo 8, fora do diretório admin há uma página chamada Admin. Esta página é utilizada para se logar no sistema. Somente para relembrar, este login é guardado e fica operante através de um Servlet Filter, também criado no capítulo citado.

Page 148: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

148148

Figura 13 – Área de entrada para a sessão administrativa Para a elaboração deste exemplo, usamos na classe UsuarioController (Listagem 22) um método chamado de pesquisar(): public Usuario pesquisar(String usuario){ Query q = usuarioDao.pesq("SELECT u FROM Usuario u WHERE u.usuario=?1"); return (Usuario) q.setParameter(1, usuario).getSingleResult(); } Uma característica específica, herdada do JDBC, é o uso de parâmetros nas queries. Com algumas adições a query JPQL, o código da query ficou u.usuario=?1, onde o número 1 é um parâmetro. Lembra-se do parâmetro “?” usado em JDBC? O método setParameter() usado para transmitir o parâmetro para a consulta. Como o resultado deve ser somente uma linha, seu tipo é Usuario e o resultado é gerado pelo método getSingleResult(). As Listagens 33, 34 e 35 demonstram os códigos necessários para serem adicionados a classe Admin.java (que acompanha a página Admin). Listagem 33. Criação do método getUsuarioController() protected UsuarioController getUsuarioController() { return (UsuarioController) getBean("UsuarioController"); } Listagem 34. Alterações no método prerender() public void prerender() { //exibe a mensagem caso o usuário tente entrar na área //administrativa sem se logar FacesContext fc = FacesContext.getCurrentInstance(); HttpSession session = (HttpSession) fc.getExternalContext().getSession(false);

Page 149: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

149149

//captura a sessão msg String msg = (String) session.getAttribute("msg"); //verifica se não é nula if (msg != null) { error(msg); } //exibe ao usuário } Listagem 35. Alterações no método do botão Logar public String logar_action() { try { //captura o login passado pelo campo usuario Usuario u = getUsuarioController().pesquisar(tfUsuario.getText().toString()); //verifica se a senha está correta, evitando SQL Injection if (tfSenha.getText().equals(u.getSenha())) { //captura a sessão do contexto criado //pelo JavaServer Faces do VW FacesContext fc = FacesContext.getCurrentInstance(); HttpSession session = (HttpSession) fc.getExternalContext().getSession(false); //cria uma sessão contendo o nome de usuario chamada logado session.setAttribute("logado", tfUsuario.getText()); //caso a sessão msg esteja com valor, a remove if (session.getAttribute("msg") != null) { session.removeAttribute("msg"); } //redireciona para a área administrativa return "logado"; } else { error("Senha inválida"); } } catch (Exception ex) { //exibe a mensagem de login ou senha inválidos error("Login ou senha inválidos"); } //retorna nulo em caso de erro, não direcionando a página alguma return null; } Observando na Listagem 35, temos a chamada ao método pesquisar(), de UsuarioController, que faz a pesquisa e retorna o objeto Usuario: Usuario u = getUsuarioController().pesquisar(tfUsuario.getText().toString()); Assim que retornado, para compará-lo a senha transmitida, temos a chamada de getSenha() de Usuario. if (tfSenha.getText().equals(u.getSenha())) { ... As demais características, como criação da Session são similares ao usado na versão SQL.

Page 150: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

150150

A página de publicação Esta página em especial também possui características próprias, pois temos um componente Drop Down List. Este componente deve ser tratado especialmente pela aplicação para que seja possível exibir a lista de editoras cadastradas. Diferente do caso em SQL, ao qual temos as opções visíveis, neste caso, com o uso da JPA, você têm que criar seu preenchimento manualmente.

Figura 14 – Aparência da página Publicar Na Listagem 36 você possui o conteúdo que será adicionado no método init() da classe SessionBean1. Listagem 36. Alterações no método init() da classe SessionBean1 public void init() { // ... omitido por não ter sido alterado //cria um list de valores recebidos do método todos() List editList = null; editList = getEditoraController().todos(); //gera uma nova lista de opções editoraOptions = new Option[editList.size()]; Iterator iter = editList.iterator(); //preenche a Drop Down List com os valores encontrados no banco de dados for (int i = 0; iter.hasNext(); i++) { Editora editora = (Editora) iter.next(); Option opt = new Option("" + editora.getId(), editora.getEditora()); editoraOptions[i] = opt; } }

Page 151: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

151151

Através do método getEditoraController() você gera um List com o resultado do método todos(), e cria um novo objeto Option. Este objeto inicia com o tamanho da listagem que comportará: new Option[editList.size()]; E depois tem seus valores e rótulos preenchidos através de um loop que varre os dados e os separa em um novo objeto Option: for (int i = 0; iter.hasNext(); i++) { Editora editora = (Editora) iter.next(); Option opt = new Option("" + editora.getId(),editora.getEditora()); editoraOptions[i] = opt; } Observe que o objeto Option possui um construtor com dois parâmetros, recebendo no primeiro o ID que será transmitido e no segundo o rótulo que será exibido ao usuário. Separadamente você teria dois métodos (setValue() e setLabel()), caso não recorresse ao construtor: Option opt = new Option(); opt.setValue(editora.getId()); //o valor que de cada item opt.setLabel(editora.getEditora()); //o rótulo de cada item Como não declaramos editoraOptions, vá ao assistente e o crie.

Figura 15 – Criando o atributo editoraOptions Depois de criado, vá até ele e gere, com o direito do mouse, no menu de contexto os métodos get e set, através de Insert Code>Getter and Setter. O resultado é exibido na Figura 16.

Page 152: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

152152

Figura 16 – Geração dos métodos get e set de editoraOptions

Ligando o Drop Down List editoras a editoraOptions Após as alterações, faça Build no projeto. Vá ao Design da página Publicar e clique com o direito sobre o componente Drop Down List editoras adicionado. Selecione no menu de contexto o item Bind to Data. Na caixa de diálogo (veja Figura 17), selecione em SessionBean1 o item editoraOptions.

Figura 17 – Seleção de editoraOptions

Adicionando código ao botão Publicar Dê um duplo clique no componente Button btPublicar e adicione o código da Listagem 37.

Page 153: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

153153

Listagem 37. O código do botão btPublicar do formulário da página public String btPublicar_action() { try { //prepara uma nova linha para inserção de dados Publicacao publicacao = new Publicacao(); Editora editora = new Editora(); Livro livro = new Livro(); //captura os valores de cada componente no formulário //e os atribui a seus determinados campos editora.setId(Integer.parseInt(editoras.getValue().toString())); livro.setId(Integer.parseInt(id.getText().toString())); publicacao.setLivro(livro); publicacao.setEditora(editora); //grava as informações no banco de dados getPublicacaoController().salvar(publicacao); //redireciona a página return "pubs"; } catch (Exception e) { error("Erro: " + e.getMessage()); } //retorna nulo em caso de erro return null; } Como ocorrido no Capítulo Extra 5, você captura os valores do campo oculto e também do Drop Down List e os grava na tabela publicacao. A diferença aqui está em como é feita esta operação. Enquanto que com acesso direto a dados é necessário apenas fazer uma referência a tabela, aqui, o responsável por salvar exige um objeto Publicacao. Este objeto precisa de dois objetos: Editora e Livro. Cada um destes dois objetos armazenará seu valor correspondente e em seguida será “envolvido” pelo objeto Publicacao, através de métodos setters. Por fim, a chamada ao método salvar(), de PublicacaoController, armazenará os dados.

Adicionando código a página Continuando no código, você deverá alterar algumas partes para que possa executar certas ações que caracterização o seu uso. A Listagem 38 exibe o que será alterado. Listagem 38. Alterações do código da página //...omitido por não ser alterado public void prerender() { //captura a variavel GET titulo this.setTitulo((String) getExternalContext(). getRequestParameterMap().get("titulo")); } //...omitido por não ser alterado

private String livid; public String getLivid() { return livid; } public void setLivid(String livid) { this.livid = livid;

Page 154: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

154154

} private String titulo; public String getTitulo() { return titulo; } public void setTitulo(String titulo) { this.titulo = titulo; } //...omitido por não ser alterado

No código do método prerender() exibido na Listagem 38, exibe um novo método não utilizado até o momento. Através de getExternalContext(), você tem acesso ao método getRequestParameterMap(), que possibilita, através de get(), capturar o valor de uma variável transmitida pelo método GET. Isso significa que transmitiremos uma variável pelo cabeçalho HTTP da página (barra de endereços) chamada de “titulo”. Esta variável será capturada e utilizada pela página. Veja mais adiante a explicação do que será transmitido. A segunda forma de receber dados pelo método GET através de uma página criada pelo Visual Web JSF é similar ao utilizado pelo JavaServer Faces, utilizando getters e setters. Como exemplo, a variável livid será utilizada para este fim.

Configurando o Hidden Field id e o título da página Volte ao Design da página. Selecione na janela Navigator a página Publicar. Vá à janela Properties e clique no botão com três pontos em Title. Altere como mostrado no trecho a seguir, na caixa de diálogo Title: Publicar livro #{admin$Publicar.titulo} Seu exemplo deverá ser similar ao da Figura 18.

Figura 18 – Alteração da propriedade Title da página Faça o mesmo com o campo oculto (Hidden Field) id. Selecione-o através da janela Navigator e na propriedade text clique no botão de três pontos. Em Use bind, selecione Bind to an Object e expanda admin/Publicar. Selecione livid e confirme.

Page 155: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

155155

Configurando faces­config.xml para trabalhar com GET Para capturar um valor transmitido pelo método GET no framework JavaServer Faces, utilizamos o <managed-property />, que deve possuir em seu valor a expressão #{param.VARIAVEL}. Veja na Listagem 39 como ficará a alteração feita no arquivo faces-config.xml: Listagem 39. Alteração em faces-config.xml para a página Publicar <managed-bean> <managed-bean-name>admin$Publicar</managed-bean-name> <managed-bean-class>br.com.integrator.admin.Publicar</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> <managed-property> <property-name>livid</property-name> <value>#{param.livid}</value> </managed-property> </managed-bean>

A página de publicações Crie uma nova página Visual Web JSF Page chamada de Publicados. Adicione os componentes da Figura 19 a seguir.

Figura 19 – Design da página Publicados Esta página também tem grandes diferenças com relação ao exemplo utilizado com SQL. Primeiro porque precisamos retornar objetos de diferentes entidades e estes precisam ter seus nomes reconhecidos pelo Visual Web JSF. Evidentemente, se estivéssemos trabalhando com JavaServer Faces “puro”, seria mais fácil.

Como será preenchido o componente Table da página Publicados O controller desenvolvido na Listagem 25 possui um método chamado de todasPublicacoes(). Este utiliza o método pesq(), em que você elabora uma query JPQL especial e determina qual seu resultado – tal como feito no caso da verificação de usuário. public List todasPublicacoes() { return publicacaoDao.pesq("SELECT p.id, l.titulo, e.editora FROM " + "Publicacao p JOIN p.editora e " + "JOIN p.livro l").getResultList(); }

Page 156: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

156156

A diferença aqui é que não estamos passando um parâmetro e estamos no caso recuperando um List, através do método getResultList(). Observando a query elaborada, temos três campos que serão retornados de três tabelas diferentes, o que no caso será três atributos diferentes de três entidades que partem de Publicacao: SELECT p.id, l.titulo, e.editora FROM Publicacao p JOIN p.editora e JOIN p.livro l O resultado deste List, é um conjunto de objetos de diferentes tipos. Somente para ilustrar, em um componente JavaServer Faces <h:dataTable /> comum, recuperaríamos estes valores através de um array, sendo a primeira coluna #{item[0]}, a segunda #{item[1]} e etc. Porém, ocorre que não estamos utilizando JavaServer Faces e sim Visual Web JavaServer Faces, que utiliza um componente diferente para renderizar uma tabela, devido a sua capacidade visual integrada ao NetBeans.

Criando um JavaBean especial Para trabalhar visualmente, com o Visual Web JSF, no componente Table, precisamos determinar os tipos dos campos. Para fazer isso, vamos criar um bean. Crie uma nova classe no pacote br.com.integrator (crie outro pacote se preferir). Chame esta classe de PublicacoesBean. Listagem 40. O bean PublicacoesBean package br.com.integrator; import java.io.Serializable; public class PublicacoesBean implements Serializable{ private Integer id; private String titulo; private String editora; private String autor; public PublicacoesBean(Integer id, String titulo, String editora, String autor) { this.id = id; this.titulo = titulo; this.editora = editora; this.autor = autor; } public PublicacoesBean(Integer id, String titulo, String editora) { this.id = id; this.titulo = titulo; this.editora = editora; } public PublicacoesBean() { } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getTitulo() { return titulo; } public void setTitulo(String titulo) { this.titulo = titulo; }

Page 157: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

157157

public String getEditora() { return editora; } public void setEditora(String editora) { this.editora = editora; } public String getAutor() { return autor; } public void setAutor(String autor) { this.autor = autor; } } O bean desenvolvido possui atributos que unem informações que virão de diversas entidades. Seu propósito é organizar o array de objetos em somente um objeto com tipos bem definidos. Isso facilitará o seu uso pelo Visual Web.

Alterando a classe SessionBean1 para utilizar o JavaBean O componente Table agora precisará ter os seus dados sendo alimentados pela classe SessionBean1. Altere a classe como mostra a Listagem 41 a seguir. Listagem 41. Alterações na classe SessionBean1 //...omitido por não haver alterações private PublicacoesBean[] publicacoes; public PublicacoesBean[] getPublicacoes() { return publicacoes; } public void setPublicacoes(PublicacoesBean[] publicacoes) { this.publicacoes = publicacoes; } public void todasPublicacoes() { //cria um ArrayList para adicionar PublicacoesBean ArrayList<PublicacoesBean> pubs = new ArrayList<PublicacoesBean>(); //pega o List retornado por todasPublicacoes()... List todasPubs = getPublicacaoController().todasPublicacoes(); //... separa em um loop for for (Iterator iter = todasPubs.iterator(); iter.hasNext();) { Object[] o = (Object[]) iter.next(); //e adiciona no ArrayList os novos objetos preenchidos PublicacoesBean pubs.add( new PublicacoesBean((Integer) o[0], (String) o[1], (String) o[2])); } //depois cria um array de PublicacoesBean do ArrayList //isso o torna acessível pelo componente Table publicacoes = (PublicacoesBean[]) pubs.toArray(new PublicacoesBean[0]); } O que será feito é bem simples. Você está adicionando um array de PublicacoesBean. Esse array será preenchido com valores alimentados pelo resultado do método todasPublicacoes() de

Page 158: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

158158

PublicacaoController. Como sabe, este devolve objetos, que serão separados através de um loop for e depois adicionados em um ArrayList através de novos objetos PublicacoesBean: for (Iterator iter = todasPubs.iterator(); iter.hasNext();) { Object[] o = (Object[]) iter.next(); pubs.add(new PublicacoesBean((Integer) o[0], (String) o[1], (String) o[2])); } Por fim, este ArrayList é transformado em array de objetos PublicacoesBean: publicacoes = (PublicacoesBean[]) pubs.toArray(new PublicacoesBean[0]); Novamente, será necessário o Build para depois ser reconhecido pelo Design das páginas.

Alterando Publicados Na classe Publicados.java (da página Publicados), será necessário adicionar no método prerender() a chamada ao método todasPublicacoes() criado em SessionBean1. Esta alteração fará com que seja executado o método quando a página for chamada, antes de ser renderizada, alimentando o componente Table. A Listagem 42 exibe esta adição. Listagem 42. Alterações do método prerender() public void prerender() { getSessionBean1().todasPublicacoes(); } Voltando ao Design, é hora de adicionar as colunas ao componente Table. Vá em Table Layout e selecione publicacoes em Get Data From. Selecione os campos mostrados na Figura 20 e crie uma nova coluna. Nesta coluna, digite Excluir em Header Text e Value Expression, selecione Hyperlink em Component Type e confirme.

Page 159: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

159159

Figura 20 – Table Layout do componente Table de Publicacoes Selecione o link Excluir, do componente Table, e dê a ele o id excluir em Properties. Dê um duplo clique sobre este link e altere seu método como mostrado na Listagem 43. Listagem 43. Alterações em Publicacoes.java protected PublicacaoController getPublicacaoController() { return (PublicacaoController) getBean("PublicacaoController"); } public String excluir_action() { try { //captura a linha atual do link de exclusão clicado RowKey rowKey = tableRowGroup1.getRowKey(); if (rowKey != null) { PublicacoesBean[] pubs = getSessionBean1().getPublicacoes(); Integer id = Integer.parseInt(rowKey.getRowId()); //seleciona somente o que será removido PublicacoesBean pubean = pubs[id]; //cria a publicação Publicacao publicacao = new Publicacao(); //envia o ID do que será excluído

Page 160: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

160160

publicacao.setId(pubean.getId()); //chama o controller para excluir a editora selecionada getPublicacaoController().excluir(publicacao); } //informa ao administrador a exclusão info("Publicação excluída!"); } catch (Exception ex) { error("Erro encontrado: " + ex); } //retorna nulo pois não muda a página return null; } Diferente do exemplo criado no Capítulo Extra 5, neste caso, você está possibilitando a exclusão das publicações. Se necessário, retorne ao Design e adicione um componente Message Group para exibição das mensagens retornadas por uso desta operação.

Adicionando autores a livros A página mostrada na Figura 21 é a mesma criada no Capítulo Extra 5, portanto será omitida sua montagem de componentes visuais.

Figura 21 – Vinculando o livro aos autores

Transportando o código do livro Diferente do link Gerar, que foi transmitido via método GET, o link que será criado na página de cadastro de Livros transmitirá via método POST, usando sessão para simplificar. Na classe SessionBean1 temos, já pronto, um atributo chamado id, que está sendo exibido na Listagem 44 apenas para ilustração:

Page 161: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

161161

Listagem 44. Alteração na classe SessionBean1 //... trecho já criado na Listagem 25 private Integer id; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; }

Alterando a classe LivroAutor.java Coloque no código Java da sua página LivroAutor e altere o método prerender() (Listagem 45), crie o atributo autorOptions (Listagem 46) e adicione uma chamada à classe AutorController (Listagem 47). Listagem 45. Alterações no método prerender() public void prerender() { List autorList = null; autorList = getAutorController().todos(); autorOptions = new Option[autorList.size()]; Iterator iter = autorList.iterator(); for (int i = 0; iter.hasNext(); i++) { Autor autor = (Autor) iter.next(); Option opt = new Option("" + autor.getId(),autor.getNome()); autorOptions[i] = opt; } } Listagem 46. Declaração do atributo autorOptions private Option[] autorOptions; public Option[] getAutorOptions() { return autorOptions; } public void setAutorOptions(Option[] autorOptions) { this.autorOptions = autorOptions; } Listagem 47. Chamando a classe AutorController protected AutorController getAutorController() { return (AutorController) getBean("AutorController"); } Retorne ao design e com o direito do mouse sobre o componente Drop Down List autores, selecione Bind to Data no menu de contexto. Na caixa de diálogo Bind to Data, expanda o item admin/LivroAutor, na guia Bind to an Object e selecione autorOptions. Confirme a caixa de diálogo.

Page 162: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

162162

Figura 22 – Seleção de autorOptions Diferente do que fora feito na página Publicar, neste caso você não colocou as opções do componente Drop Down List na classe SessionBean1. Na realidade, nem o outro era necessário, a menos que você vá utilizar em outros locais, o recomendado é colocar na página em que irá desfrutar de seus benefícios.

Alterando a página Livros Na página de cadastro de Livros (Livros.jsp), em admin, adicione mais uma coluna no componente Table, mova para antes da coluna de Publicações (veja na Figura 23).

Figura 23 – Nova coluna Autor na tabela da página Livros

Page 163: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

163163

Selecione o link Adicionar da coluna Autor, do componente Table, e altere a propriedade id para adicionar (Figura 24).

Figura 24 – Propriedade id alterada do link Adicionar do componente Table

Adicionando código ao link Adicionar Dê um duplo clique no link Adicionar, do componente Table, da página Livros (em admin) e adicione o código mostrado a seguir na Listagem 48: Listagem 48. Código do link Adicionar public String adicionar_action() { //captura a linha atual do link de adição clicado TableRowDataProvider rowData = (TableRowDataProvider) getBean("currentRow"); //o coloca no bean SessionBean1 para que possa transmitir //o valor para a página LivroAutor Livro[] livros = getSessionBean1().getLivros(); //seleciona somente o livro que será transmitido Livro livro = livros[Integer.parseInt(rowData.getTableRow().getRowId())]; //transmite para SessionBean através de id getSessionBean1().setId(livro.getId()); return "adlivroautor"; } O código deste link simplesmente adicionará o ID do livro selecionado, no componente Table, a lid de SessionBean1, no qual irá vincular o autor ao livro.

Adicionando o autor a seu livro Voltando a página LivroAutor.jsp, dê um duplo clique no botão Adicionar ao Livro e adicione o código da Listagem 49. Em seguida, adicione o apresentado pela Listagem 50.

Page 164: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

164164

Listagem 49. Código do botão Adicionar ao Livro public String btAdLivro_action() { Integer livid = getSessionBean1().getId(); try { Livro livro = new Livro(); Autor autor = new Autor(); //pesquisa o livro que sera adicionado em livro_autor livro = getLivroController().pesquisarLivro(livid); Integer autorId = Integer.parseInt(autores.getValue().toString()); //busca o Autor ao qual pertencerá o livro autor = getAutorController().pesquisarAutor(autorId); //Adiciona autor na coleção livro.getAutores().add(autor); //adiciona o livro a coleção autor.getLivros().add(livro); //grava as informações no banco de dados getLivroController().salvar(livro); getAutorController().salvar(autor); //retorna a string autlivros return "autlivros"; } catch (Exception e) { error("Erro: " + e.getMessage()); } //não vai a página alguma caso haja um erro return null; }

Listagem 50. Código de getLivroController() protected LivroController getLivroController() { return (LivroController) getBean("LivroController"); } O exemplo apresentado pela Listagem 49 é com certeza um dos maiores problemas de quem está iniciando no desenvolvimento com Hibernate. Como temos um relacionamento Many-To-Many, já explicado no princípio deste capítulo, implica em tomarmos certos cuidados para que não ocorram problemas na hora de persistir os dados. Se observar, verá que foram feitas duas pesquisas resultando em duas coleções – Autor e Livro. Isso foi feito porque estamos usando um relacionamento bidirecional. Porém, vale lembrar que temos um atributo mappedBy na anotação da entidade Livro: @ManyToMany(mappedBy = "livros") Estamos indicando ao Hibernate que devemos ter vários autores para um determinado livro, mas que não haverá repetição do mesmo autor para o mesmo livro. Se isso ocorrer, o Hibernate exclui a linha e a recria.

Page 165: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

165165

A maior questão a ser respondida aqui é: por que estamos fazendo uma pesquisa ao invés de simplesmente passar os valores e persisti-los? Há três estados possíveis para um objeto. O entendimento destes estados e as ações que os modificam, são muito importantes quando nos deparamos com algum problema:

• Transient – O objeto está em memória, porém, não foi salvo ainda; • Persistent – O objeto já está salvo, porém, em cache na EntityManager, mas pode ser que

ainda não esteja no banco de dados; • Detached – O objeto já persistido no banco de dados;

Como o atributo id de Autor está anotado com @GeneratedValue, o Hibernate percebe que há um id “setado” e imagina que provavelmente esse objeto já deve existir no banco de dados (ele é auto-incrementado e por dedução, não é feito um select), o que o leva a gerar uma exceção ao usuário: org.hibernate.PersistentObjectException: detached entity passed to persist:

br.com.integrator.entities.Autor

Se não existir o id, a mesma exceção ocorrerá. O método persist() não aceita objetos “detached”, somente “transient” e “managed”. Esta exceção não ocorreria se o id não fosse @GeneratedValue, ou se utilizarmos o método find(), de EntityManager. Bom, como estamos usando a primeira opção, resta apenas a segunda para evitar esta exceção. Portanto, temos as duas pesquisas que resultam nos objetos que desejamos: livro = getLivroController().pesquisarLivro(livid); autor = getAutorController().pesquisarAutor(autorId); Estes valores são colocados em coleção: livro.getAutores().add(autor); autor.getLivros().add(livro); As mudanças feitas somente de um lado da associação não são persistidas. Isto significa que o Hibernate tem duas representações na memória para cada associação bidirecional, uma associação de Autor para Livro e outra de Livro para Autor. Os dados são persistidos então: getLivroController().salvar(livro); //Não será salvo getAutorController().salvar(autor); //Será salvo Aqui, Livro é usado para salvar a representação em memória no banco de dados.

A página de autores publicados A última página Visual Web JSF Page a ser criada no administrador será AutoresPublicados. Sua aparência será similar a Figura 25.

Page 166: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

166166

Figura 25 – Design da página AutoresPublicados

Criando um JavaBean para AutoresPublicados Novamente, para exibir visualmente dados vindos de mais de uma entidade, será necessário criar um JavaBean, concentrando seus respectivos tipos em um só lugar. Crie uma nova classe no seu pacote principal (br.com.integrator) e altere-a como apresentado na Listagem 51. Listagem 51. Código de AutoresLivroBean package br.com.integrator; public class AutoresLivroBean { private Integer id; private String autor; private String titulo; public AutoresLivroBean() { } public AutoresLivroBean(Integer id, String autor, String titulo) { this.id = id; this.autor = autor; this.titulo = titulo; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getAutor() { return autor; } public void setAutor(String autor) { this.autor = autor; } public String getTitulo() { return titulo; }

Page 167: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

167167

public void setTitulo(String titulo) { this.titulo = titulo; } }

Utilizando o JavaBean AutoresPublicados Vá até a classe SessionBean1 e adicione o trecho mostrado na Listagem 52. Listagem 52. Trecho do código de SessionBean1 //... omitido por não haver alterações private AutoresLivroBean[] autoresLivro; public AutoresLivroBean[] getAutoresLivro() { return autoresLivro; } public void setAutoresLivro(AutoresLivroBean[] autoresLivro) { this.autoresLivro = autoresLivro; } public void todosAutoresLivros() { ArrayList<AutoresLivroBean> autoresLivros = new ArrayList<AutoresLivroBean>(); List autoresPub = getAutorController().todosAutorLivro(); for (Iterator iter = autoresPub.iterator(); iter.hasNext();) { Object[] o = (Object[]) iter.next(); autoresLivros.add( new AutoresLivroBean((Integer) o[0], (String) o[1], (String) o[2]) ); } autoresLivro = (AutoresLivroBean[]) autoresLivros.toArray(new AutoresLivroBean[0]); } Este código segue a mesma regra do criado para exibir as publicações. A diferença está no bean que será usado e na pesquisa executada para que o mesmo seja preenchido e colocado em um array. Em AutorController, como foi mostrado anteriormente na Listagem 21, há um método chamado de todosAutorLivro() que retorna um List: public List todosAutorLivro() { return autorDao.pesq("SELECT a.id, a.nome, l.titulo " + "FROM Autor a JOIN a.livros l").getResultList(); } Observe a query JPQL elaborada, ao qual temos o relacionamento Many-To-Many: SELECT a.id, a.nome, l.titulo FROM Autor a JOIN a.livros l O resultado deste List, é um conjunto de objetos de diferentes tipos, o que explica o uso de um JavaBean novamente.

Alterando AutoresPublicados Na classe AutoresPublicados.java (da página AutoresPublicados), será necessário adicionar no método prerender(), como feito em exemplo anterior, na página Publicados, a chamada ao método todosAutoresLivros() criado em SessionBean1. A Listagem 53 exibe esta adição.

Page 168: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

168168

Listagem 53. Alterações do método prerender() public void prerender() { getSessionBean1().todosAutoresLivros(); } Voltando ao Design, é hora de adicionar as colunas ao componente Table. Altere o componente Table como o quadro “Exibindo os Autores Publicados” descreve.

Exibindo os Autores Publicados

Siga estes passos para o componente Table da página AutoresPublicados, conforme visto na Figura 25:

1. No Design, clique com o direito do mouse sobre o componente Table; 2. Selecione no menu de contexto o item Table Layout; 3. Ao surgir a caixa de diálogo Table Layout, selecione autoresLivro em Get Data From, na

parte superior da janela. Deixe em Selected todos os campos (veja na Figura 26); 4. Deixe a ordem dos títulos em Header Text na seqüência: ID, Autor e Título; 5. Na guia Options digite no campo Title “Autores e Livros” e no campo Empty Data

Message “Não há autores com livros cadastrados”. Se desejar, marque Enable Pagination e confirme.

Figura 26 – Table Layout do componente Table de AutoresPublicados

Page 169: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

169169

Pesquisando livros na página principal Exatamente como feito no livro, através do Capítulo 8, você irá implementar uma busca no site. Embora iremos utilizar outra forma de acesso aos dados, muitas coisas serão semelhantes. Para facilitar e não haver dúvidas será repetido os passos aqui.

Adicionando Código a SessionBean1 A classe SessionBean1 será responsável por captar a string de pesquisa lançada pelo Text Field que existe no topo da página e transportará para a página Pesquisado.jsp. Abra a SessionBean1 e adicione um atributo chamado de pesquisado, e crie os métodos getters e setters, como mostra a Listagem 54 a seguir. Listagem 54. Alterações na classe SessionBean1 //... omitido por não haver alterações private String pesquisado=""; public String getPesquisado() { return pesquisado; } public void setPesquisado(String pesquisado) { if(pesquisado==null) pesquisado=""; this.pesquisado = pesquisado; }

Alterando o Page Fragment responsável pela pesquisa Abra o arquivo topo.jspf e dê um duplo clique no botão btBuscar (ou o id que deu ao botão). Adicione o código mostrado na Listagem 55. Listagem 55. Código no botão Buscar de topo.jspf public String btBuscar_action() { //chama pesquisado em SessionBean1 e atribui o valor //digitado no Text Field busca getSessionBean1().setPesquisado((String)busca.getText()); //retorna a string pesquisar para chegar a página Pesquisado return "pesquisar"; } No código, observe que foi chamado da classe SessionBean1 a variável pesquisado e transmitido para ela o valor digitado no Text Field busca (encontrado também em topo.jspf).

Alterando a página Pesquisado Como feito no Capítulo Extra 5, em Pesquisado.java, será recebido o valor a ser pesquisado, encontrado em SessionBean1, no qual utilizará o método pesquisar() de LivroController. Em Pesquisado, chame LivroController (Listagem 56) e depois vá até o método prerender() e adicione o código mostrado na Listagem 57.

Page 170: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

170170

Listagem 56 – Chamada de LivroController na classe Pesquisado protected LivroController getLivroController() { return (LivroController) getBean("LivroController"); } Listagem 57 – Código do método prerender() na classe Pesquisado public void prerender() { //captura o valor pesquisado String pesquisado = getSessionBean1().getPesquisado(); //transporta para o método pesquisar() de LivroController //e atribui o resultado ao array livros livros = (Livro[]) getLivroController(). pesquisar(pesquisado).toArray(new Livro[0]); } Como o método prerender() é chamado no início, antes da página ser renderizada, o valor pesquisado deve ser transferido para o método pesquisar() de LivroController e seu resultado deve ser atribuído a um array de objetos Livro (veja Listagem 58). Sua criação deverá ser feita em Pesquisado.java, o que não interfere no mesmo array existente em SessionBean1. Listagem 58 – Criação do array livros na classe Pesquisado private Livro[] livros; public Livro[] getLivros() { return livros; } public void setLivros(Livro[] livros) { this.livros = livros; } Retornando ao Design da página, execute os passos existentes no quadro “Alterando o componente Table de Pesquisado”.

Alterando o componente Table de Pesquisado

Siga estes passos para o componente Table da página Pesquisado: 1. No Design, clique com o direito do mouse sobre o componente Table; 2. Selecione no menu de contexto o item Table Layout; 3. Ao surgir a caixa de diálogo Table Layout, selecione livros (Pesquisado) em Get Data

From, na parte superior da janela. Deixe em Selected os campos mostrados na Figura 27; 4. Deixe a ordem dos títulos em Header Text na seqüência: Título, Edição, Publicação e

Imagem; 5. Na guia Options digite no campo Title “Resultados da Pesquisa Realizada” e no campo

Empty Data Message “Não foram encontrados livros no nome pesquisado”. Se desejar, marque Enable Pagination e confirme.

Page 171: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

171171

Figura 27 – Table Layout do componente Table de Pesquisado

Formulários virtuais para a pesquisa Um problema que este sistema de pesquisa possui é o fato de estar fora de um formulário, o que impede de criar um formulário virtual, já que é um fragmento de página e não uma página completa. Para páginas que possuem formulário, como de Contato e Admin, ao fazer uma busca um erro ocorrerá, onde haverá a validação dos campos destes formulários. Para evitá-los, tanto na página Contato.jsp como em Admin.jsp, você irá adicionar o formulário virtual manualmente, como mostrado na Listagem 59 seguir: Listagem 59 – Criação do array livros na classe Pesquisado ... <webuijsf:form binding="#{Contato.form1}" id="form1" virtualFormsConfig="pesquisa | | topo:btBuscar topo:busca, ...

A página de contato Como estamos utilizando neste estudo de caso o Tomcat, você deve adicionar ao projeto bibliotecas JARs adicionais, que já estão inclusas no GlassFish. Veja no quadro “Trabalhando com JavaMail”.

Page 172: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

172172

Trabalhando com JavaMail

Para adicionar o JavaMail a seu projeto, quando utilizar o Tomcat, faça os seguintes passos: 1. Baixe o JavaMail no endereço http://java.sun.com/products/javamail/index.html. 2. Pegue o arquivo mail.jar e adicione ao seu projeto. De preferência, crie uma nova

biblioteca, para utilizar em outros projetos (Figura 28). 3. Baixe um arquivo chamado JavaBeans Activation Framework. 4. Descompacte e pegue o arquivo activation.jar e coloque junto ao arquivo mail.jar.

A API JavaMail é muito completa e complexa, tendo diversas utilidades, além de somente enviar e-mail, o que não será abordado neste livro.

Figura 28 – Criação de uma nova biblioteca no NetBeans

A navegação de páginas Diferente do que foi feito no Capítulo Extra 5, neste caso, não iremos adicionar item por item para gerar a navegação, o que fora feito manualmente no primeiro caso. Aqui, vamos utilizar os recursos do JavaServer Faces para minimizar o tamanho da navegação, o que fora feito anteriormente para criar a pesquisa. Veja o resultado final do arquivo faces-config.xml mostrado na Figura 29. Na Listagem 60 você tem a navegação configurada na íntegra, com destaques.

Page 173: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

173173

Figura 29 – Navegação do aplicativo

Page 174: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

174174

Listagem 60 – Navegação das páginas em faces-config.xml <faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"> <application> <variable-resolver> org.springframework.web.jsf.DelegatingVariableResolver </variable-resolver> </application> <managed-bean> <managed-bean-name>UsuarioController</managed-bean-name> <managed-bean-class> br.com.integrator.controller.UsuarioController </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>usuarioDao</property-name> <value>#{usuarioDao}</value> </managed-property> </managed-bean> <managed-bean> <managed-bean-name>LivroController</managed-bean-name> <managed-bean-class> br.com.integrator.controller.LivroController </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>livroDao</property-name> <value>#{livroDao}</value> </managed-property> </managed-bean> <managed-bean> <managed-bean-name>EditoraController</managed-bean-name> <managed-bean-class> br.com.integrator.controller.EditoraController </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>editoraDao</property-name> <value>#{editoraDao}</value> </managed-property> </managed-bean> <managed-bean> <managed-bean-name>AutorController</managed-bean-name> <managed-bean-class> br.com.integrator.controller.AutorController </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>autorDao</property-name> <value>#{autorDao}</value> </managed-property> </managed-bean> <managed-bean> <managed-bean-name>PublicacaoController</managed-bean-name> <managed-bean-class> br.com.integrator.controller.PublicacaoController </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>publicacaoDao</property-name> <value>#{publicacaoDao}</value> </managed-property> </managed-bean> <managed-bean> <managed-bean-name>SessionBean1</managed-bean-name>

Page 175: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

175175

<managed-bean-class>br.com.integrator.SessionBean1</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>Page1</managed-bean-name> <managed-bean-class>br.com.integrator.Page1</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>ApplicationBean1</managed-bean-name> <managed-bean-class>br.com.integrator.ApplicationBean1</managed-bean-class> <managed-bean-scope>application</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>RequestBean1</managed-bean-name> <managed-bean-class>br.com.integrator.RequestBean1</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>admin$menu</managed-bean-name> <managed-bean-class>br.com.integrator.admin.menu</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>menu</managed-bean-name> <managed-bean-class>br.com.integrator.menu</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>Contato</managed-bean-name> <managed-bean-class>br.com.integrator.Contato</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>Admin</managed-bean-name> <managed-bean-class>br.com.integrator.Admin</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>topo</managed-bean-name> <managed-bean-class>br.com.integrator.topo</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>admin$Livros</managed-bean-name> <managed-bean-class>br.com.integrator.admin.Livros</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <!--De qualquer lugar acessa as paginas--> <navigation-rule> <from-view-id>/*</from-view-id> <navigation-case> <from-outcome>admin</from-outcome> <to-view-id>/Admin.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>livroscads</from-outcome> <to-view-id>/Livros.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>pesquisar</from-outcome> <to-view-id>/Pesquisado.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>contato</from-outcome> <to-view-id>/Contato.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>autores</from-outcome> <to-view-id>/Autores.jsp</to-view-id> </navigation-case> </navigation-rule>

Page 176: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

176176

<!--Loga para a área administrativa--> <navigation-rule> <from-view-id>/Admin.jsp</from-view-id> <navigation-case> <from-outcome>logado</from-outcome> <to-view-id>/admin/Livros.jsp</to-view-id> </navigation-case> </navigation-rule> <managed-bean> <managed-bean-name>admin$Editoras</managed-bean-name> <managed-bean-class>br.com.integrator.admin.Editoras</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <!--Navega de qualquer lugar de /admin--> <navigation-rule> <from-view-id>/admin/*</from-view-id> <navigation-case> <from-outcome>cadliv</from-outcome> <to-view-id>/admin/Livros.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>cadaut</from-outcome> <to-view-id>/admin/Autores.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>caded</from-outcome> <to-view-id>/admin/Editoras.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>pubs</from-outcome> <to-view-id>/admin/Publicados.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>logout</from-outcome> <to-view-id>/Admin.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>autlivros</from-outcome> <to-view-id>/admin/AutoresPublicados.jsp</to-view-id> </navigation-case> </navigation-rule> <managed-bean> <managed-bean-name>admin$Autores</managed-bean-name> <managed-bean-class>br.com.integrator.admin.Autores</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>admin$Publicados</managed-bean-name> <managed-bean-class>br.com.integrator.admin.Publicados</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>admin$Publicar</managed-bean-name> <managed-bean-class>br.com.integrator.admin.Publicar</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> <managed-property> <property-name>livid</property-name> <value>#{param.livid}</value> </managed-property> </managed-bean> <managed-bean> <managed-bean-name>Livros</managed-bean-name> <managed-bean-class>br.com.integrator.Livros</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>admin$LivroAutor</managed-bean-name> <managed-bean-class>br.com.integrator.admin.LivroAutor</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>admin$AutoresPublicados</managed-bean-name> <managed-bean-class> br.com.integrator.admin.AutoresPublicados

Page 177: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

177177

</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <navigation-rule> <from-view-id>/admin/LivroAutor.jsp</from-view-id> <navigation-case> <from-outcome>autlivros</from-outcome> <to-view-id>/admin/AutoresPublicados.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/admin/Livros.jsp</from-view-id> <navigation-case> <from-outcome>adlivroautor</from-outcome> <to-view-id>/admin/LivroAutor.jsp</to-view-id> </navigation-case> </navigation-rule> <managed-bean> <managed-bean-name>Pesquisado</managed-bean-name> <managed-bean-class>br.com.integrator.Pesquisado</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>Autores</managed-bean-name> <managed-bean-class>br.com.integrator.Autores</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> </faces-config>

Alterando os menus Para melhor esclarecimento, será mostrado nas Listagens 61 e 62 os menus da página principal e da área administrativa. Listagem 61. Os métodos dos links do menu Principal public String livros_action() { // navega para os livros cadastrados return "livroscads"; } public String autores_action() { // navega para os autores cadastrados return "autores"; } public String admin_action() { // navega para a página de login para o administrador return "admin"; } public String contato_action() { // navega para a página de contato return "contato"; } Listagem 62. Os métodos dos links do menu Administrativo public String cadaut_action() { //torna nulo o valor de id getSessionBean1().setId(null); return "cadaut"; } public String cadliv_action() { //torna nulo o valor de id getSessionBean1().setId(null); return "cadliv"; }

Page 178: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

178178

public String logout_action() { FacesContext fc = FacesContext.getCurrentInstance(); HttpSession session = (HttpSession) fc.getExternalContext().getSession(false); //expira a sessão session.invalidate(); return "logout"; } public String caded_action() { //torna nulo o valor de id getSessionBean1().setId(null); return "caded"; } public String publicacoes_action() { //torna nulo o valor de id getSessionBean1().setId(null); return "pubs"; } public String autpub_action() { //torna nulo o valor de id getSessionBean1().setId(null); return "autlivros"; }

Configurando um Pool para a conexão Podemos adicionar as configurações do arquivo persistence.xml, uma espécie de “pool” de conexões para o uso com o Hibernate, ao qual melhora o desempenho de nossa aplicação. Para o caso, será utilizado é o C3P0 (veja a Listagem 63 para mais detalhes). <!—Configuração do pool de c3p0--> <property name="hibernate.c3p0.min_size" value="5" /> <property name="hibernate.c3p0.max_size" value="20" /> <property name="hibernate.c3p0.timeout" value="300" /> <property name="hibernate.c3p0.max_statements" value="50" /> <property name="hibernate.c3p0.idle_test_period" value="3000"/>

O c3p0 Para configurar o c3p0, você deverá incluir a biblioteca c3p0-0.9.1.1.jar em sua aplicação. Este arquivo, com esta versão, está junto com as bibliotecas encontradas no Spring Framework 2.5. Para melhor compreender o que foi feito, há uma breve descrição dos novos elementos adicionados no arquivo, listados a seguir:

• hibernate.cache.provider_class - Configura a classe do provedor de cache; • hibernate.c3p0.min_size - A quantidade mínima de conexões com o banco de dados do

pool; • hibernate.c3p0.max_size - A quantidade máxima de conexões com o banco de dados do

pool; • hibernate.c3p0.timeout - O tempo máximo de duração de um comando ao banco; • hibernate.c3p0.max_statements - Número máximo de comandos simultâneos em

execução; • hibernate.c3p0.idle_test_period - Intervalo de tempo para que o pool teste se a conexão

continua ativa; O resultado final de seu arquivo persistence.xml, será similar ao da Listagem 63, mais adiante.

Page 179: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

179179

Trabalhando com cache de objetos Frameworks ORM como o Hibernate, se preocupam com o desempenho das aplicações, ao qual podemos contar com um esquema de cache de objetos, evitando idas desnecessárias ao banco de dados a cada consulta semelhante. Os caches de objetos, quando bem montados, podem tornar a aplicação ainda mais rápida do que a mesma aplicação feita com o uso direto de JDBC. Na JPA, e com o Hibernate, há um sistema de cache automático e não configurado de EntityManager, ao qual é conhecido como “cache de primeiro nível”. O cache de primeiro nível é um cache relacionado a uma única sessão (EntityManager) do Hibernate, onde esse cache garante que você vai acessar sempre os mesmos objetos dentro da mesma. Esse cache não tem nenhuma preocupação com performance, o seu objetivo é de apenas garantir a integridade das informações dentro de uma mesma sessão. Felizmente, possuímos uma alternativa de ter um “cache de segundo nível”, que é opcional e é o que nós veremos aqui. Para utilizar o cache de segundo nível, você deve levar em conta algumas considerações, onde uma das mais importantes é que, se houverem outras aplicações fazendo inserções e atualizações no mesmo banco de dados, ao qual o Hibernate está conectado, é melhor nem utilizar o cache, porque outra aplicação pode atualizar informações que podem não ser refletidas pelo Hibernate, uma vez que estas se encontram em cache. Um detalhe importante é que sua aplicação deve ter mais envolvimento com leituras do que com atualizações ou inserções de dados. Do contrário, o cache pode até mesmo diminuir a performance da aplicação. Como o objetivo do exemplo é mostrar na prática seu uso, vamos apenas levar em consideração que a aplicação será muito usada para leitura e, como foi concebido, não há níveis hierárquicos de administradores, o que indica ser um sistema pequeno e de poucas mudanças.

Configurando o cache O arquivo persistence.xml teve uma pequena alteração com relação ao mostrado pelo Capítulo 10 do livro, adicionando agora o cache de segundo nível com EhCache. Listagem 63. O arquivo persistence.xml <?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" 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_1_0.xsd"> <persistence-unit name="livraria"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <!--Configuração do Hibernate--> <property name="hibernate.archive.autodetection" value="class, hbm" /> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" /> <property name="hibernate.connection.url" value="jdbc:mysql://localhost/livraria" /> <property name="hibernate.connection.username" value="edson" /> <property name="hibernate.connection.password" value="integrator" /> <!--Configuração de Debug--> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> <!—Configuração do pool de c3p0-->

Page 180: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

180180

<property name="hibernate.c3p0.min_size" value="5" /> <property name="hibernate.c3p0.max_size" value="20" /> <property name="hibernate.c3p0.timeout" value="300" /> <property name="hibernate.c3p0.max_statements" value="50" /> <property name="hibernate.c3p0.idle_test_period" value="3000"/> </properties> </persistence-unit> </persistence>

O EhCache Hibernate tem alguns métodos úteis que podem ajudar a testar e afinar seu cache. Enquanto que EntityManager fornece um cache de primeiro nível, podemos adicionar um segundo nível a aplicação. Isso é possível através de hibernate.cache.use_second_level_cache, você obtém um cache de segundo nível. O EhCache é o framework padrão de cache do Hibernate. O plugin do Spring, utilizado no projeto, já o tem colocado em sua biblioteca. O que vamos fazer agora é configurá-lo. Listagem 64. O arquivo persistence.xml completo <?xml version="1.0" encoding="UTF-8"?> <persistence version="1.0" 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_1_0.xsd"> <persistence-unit name="livraria"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <!--Configuração do Hibernate--> <property name="hibernate.archive.autodetection" value="class, hbm" /> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" /> <property name="hibernate.connection.url" value="jdbc:mysql://localhost/livraria" /> <property name="hibernate.connection.username" value="edson" /> <property name="hibernate.connection.password" value="integrator" /> <!--Configuração de Debug--> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> <!--Configuração do segundo nível de cache--> <property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.EhCacheProvider" /> <property name="hibernate.cache.provider_configuration" value="/ehcache.xml" /> <property name="hibernate.cache.use_minimal_puts" value="false" /> <property name="hibernate.cache.use_query_cache" value="true" /> <property name="hibernate.cache.use_second_level_cache" value="true" /> <property name="hibernate.cache.use_structured_entries" value="true" /> <property name="hibernate.ejb.classcache.br.com.integrator.entities.Livro" value="read-write"/> <property name="hibernate.ejb.classcache.br.com.integrator.entities.Autor"

Page 181: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

181181

value="read-write" /> <property name="hibernate.ejb.classcache.br.com.integrator.entities.Editora" value="read-write" /> <property name="hibernate.ejb.classcache.br.com.integrator.entities.Publicacao" value="read-write" /> <property name="hibernate.ejb.classcache.br.com.integrator.entities.Usuario" value="read-write" /> <!—Configuração do pool de c3p0--> <property name="hibernate.c3p0.min_size" value="5" /> <property name="hibernate.c3p0.max_size" value="20" /> <property name="hibernate.c3p0.timeout" value="300" /> <property name="hibernate.c3p0.max_statements" value="50" /> <property name="hibernate.c3p0.idle_test_period" value="3000"/> </properties> </persistence-unit> </persistence> Para trabalhar com o cache, é necessário configurar o arquivo persistence.xml, conforme a Listagem 64 completa apresenta. <!--Configuração do segundo nível de cache--> <property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.EhCacheProvider" /> <property name="hibernate.cache.provider_configuration" value="/ehcache.xml" /> <property name="hibernate.cache.use_minimal_puts" value="false" /> <property name="hibernate.cache.use_query_cache" value="true" /> <property name="hibernate.cache.use_second_level_cache" value="true" /> <property name="hibernate.cache.use_structured_entries" value="true" /> <property name="hibernate.ejb.classcache.br.com.integrator.entities.Livro" value="read-write"/> <property name="hibernate.ejb.classcache.br.com.integrator.entities.Autor" value="read-write" /> <property name="hibernate.ejb.classcache.br.com.integrator.entities.Editora" value="read-write" /> <property name="hibernate.ejb.classcache.br.com.integrator.entities.Publicacao" value="read-write" /> <property name="hibernate.ejb.classcache.br.com.integrator.entities.Usuario" value="read-write" /> Para habilitar o cache na aplicação, é necessário escolher uma implementação da interface CacheProvider e adicioná-la a configuração do Hibernate. A implementação usada é EhCacheProvider, uma implementação não-clusterizável(não deve ser utilizada em um ambiente de cluster) da interface CacheProvider para o Hibernate. Isso é indicado na seguinte linha: <property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.EhCacheProvider" />

Page 182: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

182182

O segundo nível de cache no projeto Para configurar as propriedades do cache para a aplicação, é necessário adicionar o arquivo ehcache.xml no classpath da aplicação (veja a Figura 30). Crie o arquivo da Listagem 65: Listagem 65. O arquivo ehcache.xml completo <?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd"> <diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskPersistent="true" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> <cache name="br.com.integrator.entities.Livro" maxElementsInMemory="300" eternal="true" overflowToDisk="false" /> <cache name="br.com.integrator.entities.Autor" maxElementsInMemory="300" eternal="true" overflowToDisk="false" /> <cache name="br.com.integrator.entities.Editora" maxElementsInMemory="300" eternal="true" overflowToDisk="false" /> <cache name="br.com.integrator.entities.Publicacao" maxElementsInMemory="300" eternal="true" overflowToDisk="false" /> <cache name="br.com.integrator.entities.Usuario" maxElementsInMemory="300" eternal="true" overflowToDisk="false" /> <cache name="br.com.integrator.entities.Autor.livros" maxElementsInMemory="300" eternal="true" overflowToDisk="false" /> <cache name="br.com.integrator.entities.Livro.autores" maxElementsInMemory="300" eternal="true" overflowToDisk="false" /> </ehcache> O arquivo de configuração do EhCache é simples, iniciando com o primeiro elemento <diskStore/>, que contém a localização de onde deve ficar o arquivo que está utilizando o cache (se algum objeto não estiver sido guardado na memória). Neste elemento, você possui o atributo path, que pode indicar um diretório ou usar os seguintes valores:

• user.home – Este valor indica o diretório raiz do usuário; • user.dir – Este valor indica o diretório corrente para aplicação; • java.io.tmpdir – Este valor indica o diretório temporário pra a máquina virtual;

Page 183: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

183183

Olhando a Listagem 65, temos no elemento <cache /> (que contém as informações específicas de cada região de cache), o atributo name que, neste caso, possui como nome do cache o nome completo da classe. Caso o nome do cache não seja encontrado, o cache padrão será utilizado. Este cache também é configurado no arquivo ehcache.xml com ao elemento <defaultCache />. Os principais elementos utilizados são apresentados a seguir:

• maxElementsInMemory – Determina o número máximo de objetos que podem ficar armazenados em memória;

• eternal – Quando configurado com o valor true, significa que o cache nunca vai expirar; • timeToIdleSeconds – O tempo em segundos que um objeto pode permanecer inutilizado no

cache; • timeToLiveSeconds – O tempo em segundos que um objeto pode ficar em cache; • overflowToDisk – Quando configurado com o valor true e, caso o limite de objetos em

memória, seja superior ao definido pela propriedade maxElementsInMemory, as informações serão armazenadas em disco.

Figura 30 – Destaque para a localização do arquivo ehcache.xml Em seguida, você deve adicionar a anotação do cache nas entidades que deseja colocar em segundo nível. Para isso, altere as entidades como mostra as Listagens de 66 a 70 a seguir: Listagem 66. A entidade Autor package br.com.integrator.entities; import java.io.Serializable; import java.util.Date; import java.util.Set; import javax.persistence.*; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; @Entity @Table(name = "autores")

Page 184: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

184184

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class Autor implements Serializable { //... omitido por não haver alterações @ManyToMany(cascade={CascadeType.MERGE,CascadeType.PERSIST}) @JoinTable(name="livro_autor", joinColumns=@JoinColumn(name="autor_id"), inverseJoinColumns=@JoinColumn(name="livro_id")) @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) private Set<Livro> livros; //... omitido por não haver alterações Listagem 67. A entidade Livro package br.com.integrator.entities; import java.io.Serializable; import java.util.Collection; import java.util.Set; import javax.persistence.*; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; @Entity @Table(name = "livros") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class Livro implements Serializable { //... omitido por não haver alterações @ManyToMany(mappedBy="livros") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) private Set<Autor> autores; //... omitido por não haver alterações Listagem 68. A entidade Editora package br.com.integrator.entities; import java.io.Serializable; import java.util.Collection; import javax.persistence.*; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; @Entity @Table(name = "editoras") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class Editora implements Serializable { //... omitido por não haver alterações Listagem 69. A entidade Publicacao package br.com.integrator.entities; import java.io.Serializable; import javax.persistence.*; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; @Entity @Table(name = "publicacao")

Page 185: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

185185

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class Publicacao implements Serializable { //... omitido por não haver alterações Listagem 70. A entidade Usuario package br.com.integrator.entities; import java.io.Serializable; import javax.persistence.*; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; @Entity @Table(name = "usuarios") @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class Usuario implements Serializable { //... omitido por não haver alterações Ao adicionar a anotação @Cache, de org.hibernate.annotations.Cache, você ativa o cache para a entidade. A anotação possui CacheConcurrencyStrategy.READ_WRITE, de org.hibernate.annotations.CacheConcurrencyStrategy, indicando que vamos utilizar o tipo read-write (leitura-escrita), ao qual permite a leitura e gravação de novas informações. Há outros tipos, como READ_ONLY, para informações que não nunca serão atualizadas. Há outros valores possíveis para o atributo usage, que determina a estratégia do cache concorrente. Estes valores podem ser: NONE, READ_ONLY, NONSTRICT_READ_WRITE, READ_WRITE, TRANSACTIONAL. Veja mais detalhes no quadro “Detalhes da utilização do cache no Hibernate”.

Detalhes da utilização do cache no Hibernate

Utilizar corretamente o cache pelo Hibernate determina como controlar o acesso e o comportamento dos objetos cacheados, definidos pelo atributo usage da anotação @Cache:

• READ_ONLY – Utilizado quando a aplicação não atualiza as informações, apenas a lê; • READ_WRITE – Deve ser utilizado quando a aplicação faz atualizações nos objetos que estão

no cache, mas não deve ser utilizado se o nível de isolamento das transações for ISOLATION_SERIALIZABLE;

• NONSTRICT_READ_WRITE – Utilizado quando a quantidade de atualizações dos objetos é pequena e quando é pouco provável que duas transações vão tentar atualizar o mesmo objeto;

• TRANSACTIONAL – só pode ser utilizado em um ambiente com suporte a JTA (como um servidor de aplicações como o GlassFish ou Gerônimo). Esse tipo de cache é totalmente transacional e pode ser utilizado com qualquer nível de isolamento das transações. O cache suportado oficialmente pelo Hibernate 3.x é o JBoss TreeCache;

Para sua sorte, na maioria das vezes será utilizado os modos READ_WRITE ou NONSTRICT_READ_WRITE, mas para o uso, é recomendável avaliar o comportamento das transações do seu sistema. Em vários casos, o cache de segundo nível não é recomendado.

Page 186: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

186186

Apêndice Extra B 

O MySQL MySQL é um sistema de gerenciamento de banco de dados relacional, multiencadeado, de código-fonte aberto e nível corporativo. O MySQL foi desenvolvido por uma empresa de consultoria na Suécia chamada inicialmente de TcX, depois, com a popularidade do MySQL, passou a se chamar MySQL AB. Seu desenvolvimento ocorreu quando estavam precisando de um sistema de banco de dados que fosse extremamente rápido e flexível. Foi, assim então, que eles criaram o MySQL, que é vagamente baseado em outro sistema de gerenciamento de banco de dados chamado de mSQL. O MySQL é rápido, flexível e confiável. É utilizado em muitos lugares por todo o mundo. Recentemente, esta empresa foi adquirida pela Sun Microsystems. Obs.: A propósito, à parte ''AB'' do nome da companhia é o acrônimo para a palavra sueca ''aktiebolag'', ou ''sociedade anônima''. Ela é traduzida para ''MySQL, Inc.'' De fato, MySQL Inc. e MySQL GmbH são exemplos de subsidiárias da MySQL AB. Elas estão localizadas nos EUA e Alemanha, respectivamente.

O que é um banco de dados relacional? Um banco no mundo de cimento e tijolo é o lugar onde guardamos dinheiro. Um banco de dados também guarda, só que neste caso são dados. Chamamos de dados tudo que possamos inserir no computador, números, letras, caracteres, imagens e etc. Um banco de dados relacional é uma composição de tabelas e colunas que se relacionam entre si. Esses relacionamentos são baseados em um valor-chave que é contido em cada tabela, em uma coluna.

Instalando o banco de dados O MySQL tem diferentes formas de instalação quando se trata de sistemas operacionais. No caso do Windows, você pode baixar a última distribuição através do site: http://www.mysql.com/downloads

Instalando no Windows Procure pelo formato executável. O arquivo vem compactado no formato .zip. Descompacte e instale. A instalação, como não poderia deixar de ser, é feita por um assistente. Siga os passos até a finalização. Caso sua máquina tenha o sistema operacional Windows pertencente a família NT( NT, 2000 ou XP), o MySQL é instalado como serviço. Então basta iniciar ou parar o serviço, encontrado no Painel de Controle>Ferramentas Administrativas>Serviços. Você também pode utilizar o comando pelo prompt, desde que você saiba o nome do serviço do seu MySQL:

Page 187: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

187187

Para iniciar o serviço: net start mysql Para parar o serviço: net stop mysql

Instalando o MySQL no Linux O MySQL Server pode ser instalado no Linux de várias formas. A forma recomendada é a que está em formato RPM. Você deve baixar dois arquivos para instalar o MySQL na sua máquina. Esses arquivos são: MySQL-server-[versão].i386.rpm – para instalar o servidor mysqld no Linux MySQL-client-[versão].i386.rpm – para instalar o cliente mysql para executar os comandos no Linux. A instalação poderá ser feita através do comando rpm, no Shell do seu Linux. Um exemplo seria: Shell> rpm –ivh MySQL-server-5.0.1.i386.rpm MySQL-client-5.0.1.i386.rpm A versão RPM já vem com pré-configurações e assim que ocorrer a instalação, para iniciar ou parar o servidor, a seguinte sintaxe poderá ser feita: Shell>/etc/init.d/./mysql start – para iniciar o servidor MySQL Shell>/etc/init.d/./mysql stop – para parar o servidor MySQL

Acessando o banco de dados MySQL

No Windows Se você estiver usando o sistema operacional Windows e utilizou a instalação padrão do programa, abra o prompt de comando e digite a seqüência: cd\mysql\bin Lembrando que você deve estar no drive em que o MySQL está instalado. Por padrão você o instala no drive C. Digitando o comando a seguir você entra no MySQL. mysql –u root -p Tecle ENTER e receberá o pedido de senha: password Digite a senha que você configurou na instalação e tecle ENTER novamente. Nota: Versões mais modernas do MySQL para o sistema operacional Windows não necessitam de tantos passos para iniciar, bastando ir até o atalho encontrado no menu Iniciar do sistema e no atalho do MySQL iniciar o prompt de comando encontrado neste local.

Page 188: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

188188

No Linux Se você utilizou a instalação binária, em rpm (recomendado), basta abrir o terminal e digitar a seqüência: shell>mysql –u root -p Se já estiver logado como root, no seu sistema operacional, não há necessidade de colocar o –u root -p depois do comando mysql. Somente –p caso haja uma senha.

Comandos essenciais para o uso do MySQL Muitos são as instruções SQL para que você venha a dominar um banco de dados. Porém, alguns comandos são imprescindíveis para que você possa trabalhar. Estes comandos são descritos a seguir.

O comando CREATE Há muitas maneiras diferentes de criar banco de dados no MySQL. Ao criar um banco de dados, você normalmente terá o layout inteiro pronto. Normalmente adicionaria as tabelas imediatamente depois de criar o banco de dado, mas, teremos uma etapa por vez. A primeira etapa para criar um banco de dados no MySQL é inserir o comando CREATE DATABASE nome_banco_de_dados da SQL (Structured Query Language) no monitor MySQL, onde nome_banco_de_dados é o nome do banco de dados que você está criado. No prompt de comando, no monitor do MySQL, insira o seguinte comando: mysql> CREATE DATABASE relatorios; Note que não foi utilizado acentuação e em casos de palavras compostas não insira espaços, se for o caso insira sublinhado “ _ ” .

O comando USE  Depois de confirmado a criação do banco de dados, você deverá utilizar o comando USE para utilizar o banco de dados relatorios. USE relatorios; Um ponto importante é que o MySQL não torna ativo o banco de dados que você criou, isso deve ser implícito.

O comando DROP O comando DROP é semelhante ao comando CREATE. Enquanto o último cria um banco de dados, o primeiro exclui. O comando DROP do SQL é imperdoável. Não há caixas de confirmação para ver se você tem certeza. Este comando exclui o banco de dados e tudo o que estiver nele. É só ir até o prompt de comando e no monitor do MySQL e digitar: mysql> DROP DATABASE relatorios; Isso excluirá o banco de dados veículos e tudo o que estiver nele.

Page 189: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

189189

Criando tabelas Criar tabela no MySQL é uma tarefa relativamente fácil. Para se criar uma tabela basta usar a seqüência: shell>mysql –u root –p shell>DIGITE AQUI SUA SENHA Após estar no monitor do MySQL digite a seguinte seqüência: mysql> CREATE DATABASE relatorios; mysql> USE relatorios; mysql> CREATE TABLE categorias ( -> CategoriaID int(11) NOT NULL auto_increment, -> categoria varchar(40) NOT NULL, -> descricao longtext, -> PRIMARY KEY (CategoriaID), -> KEY categoria (categoria) -> ) ENGINE=InnoDB

O comando SHOW Assim que criada sua primeira tabela. Para ver o resultado basta digitar a seqüência: SHOW TABLES FROM relatorios; Para ver as colunas que existem na sua tabela digite: SHOW COLUMNS FROM categorias;

O comando DESCRIBE Se preferir, o comando DESCRIBE faz a mesma coisa que SHOW, mostrando as colunas existentes em sua tabela. DESCRIBE categorias; Ou simplesmente: DESC categorias;

Alterando tabelas existentes Agora que você criou a sua tabela o que aconteceria se você precisasse alterar algo que fez? Confira os seguintes exemplos para alterar o nome da tabela, tipo de dados e o nome da coluna:

Alterando o nome da coluna Usando a cláusula CHANGE você pode alterar o nome da coluna da sua tabela: ALTER TABLE produtos CHANGE prod_nome produto_nome VARCHAR(150);

Page 190: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

190190

Alterando o tipo de coluna O tipo pode ser alterado usando a cláusula MODIFY: ALTER TABLE categorias MODIFY CategoriaID VARCHAR(200) NOT NULL;

Renomeando uma tabela Renomear o nome de uma tabela, também se usa ALTER TABLE, mas com a cláusula RENAME: ALTER TABLE produtos RENAME tb_categorias;

Excluindo / adicionando colunas e tabelas Como você pode ver quando uma coluna é criada ou uma tabela estas não são escritas na pedra e podem ser alteradas facilmente. Isso também implica em adicionar colunas em uma tabela existente ou excluí-la.

Eliminando tabelas e colunas O comando DROP também é utilizado para eliminar as colunas de uma tabela. Para excluir uma tabela existente execute a seguinte seqüência: DROP TABLE categorias; Para excluir somente uma coluna execute a seguinte seqüência: ALTER TABLE categorias DROP descricao ; Isso excluirá a coluna e todas as informações que você armazenou.

Adicionando colunas O comando ADD é o responsável pela inserção de uma nova coluna. ALTER TABLE categorias ADD descricao TEXT;

Adicionando colunas após outra determinada coluna O comando AFTER adiciona a nova coluna na tabela após o nome mencionado. ALTER TABLE categorias ADD descricao TEXT AFTER categoria;

Utilizando índices Um índice é um arquivo estruturado que facilita o acesso a dados. Isso significa que um índice na coluna correta aumentará a velocidade de uma consulta consideravelmente. Um índice trabalha da mesma forma que pastas com separador alfabético em um gabinete de arquivo ele permite pular para a parte do alfabeto que você está procurando.

Page 191: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

191191

Decidindo quais colunas incluir no índice Você deve colocar um índice na(s) coluna(s) que utilizará com mais freqüência como filtro em suas consultas. Os índices também funcionam melhor em colunas que contêm dados únicos. Essa é uma das razões pela as quais chaves são normalmente suas melhores escolhas para índices. Essa também pode ser uma das razões que as pessoas confundem chaves e índices. Uma chave ajuda a definir a estrutura de um banco de dados, ao passo que índice apenas aprimora o desempenho. Um índice pode ser composto de uma ou mais colunas. Você também pode ter mais de um índice em uma tabela.

Criando um índice Por padrão, o MySQL cria um índice se você declara uma coluna como uma chave primária. Não há necessidade de criar um índice nessa coluna; caso contrário você teria dois índices em uma mesma coluna. A sintaxe para criar um índice em uma coluna: ALTER TABLE categorias ADD INDEX idx_cat(categoria);

Excluindo índices Excluir um índice é tão simples quanto criar. A sintaxe é a mesma que excluir uma coluna ou uma tabela: DROP INDEX nomedoindice ON nomedatabela; Ou... ALTER TABLE nomedatabela DROP INDEX nomedoindice; Para alterar uma tabela eliminando uma chave primária, utilize a seguinte sintaxe: ALTER TABLE nomedatabela DROP PRIMARY KEY; Nota: Se você estiver usando uma coluna com AUTO_INCREMENT, você não excluirá a chave primária enquanto não retirar esse modificador.

Tipos de tabelas O MySQL possui uma característica um pouco diferente dos outros sistemas gerenciadores de banco de dados, uma vez que no MySQL é possível escolher o tipo da tabela no momento da criação. O formato de armazenamento dos dados, bem como alguns recursos do banco de dados são dependentes do tipo de tabela escolhido. A definição do tipo de tabela pode ser feita na criação da tabela, como você pode ver a seguir: CREATE TABLE teste ( id INT NOT NULL, nome VARCHAR(30) NOT NULL, PRIMARY KEY (id) ) ENGINE=MyISAM;

Page 192: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

192192

No comando criado, o tipo da tabela, indicado em TYPE=MyISAM, significa que você está criando uma tabela com o tipo MyISAM, que é o padrão das tabelas, caso não seja informado o TYPE. A partir da versão 4.0.18 você pode utilizar ENGINE como sinônimo de TYPE. Os tipos mais comuns de tabelas criadas são o MyISAM (padrão) e o InnoDB(suporta transações):

O tipo MyISAM Este é o tipo de tabela padrão do MySQL. Caso não seja informado o tipo de tabela, o MySQL criará a tabela do tipo MyISAM. O tipo de tabela padrão pode ser alterado incluindo-se no arquivo de configuração, chamado de my.cnf (no Linux) ou my.ini (no Windows), a opção a seguir: default-storage-engine=INNODB

As tabelas MyISAM são armazenadas em 3 arquivos, com o mesmo nome da tabela, mas com extensões diferentes:

• .FRM que armazena a definição da tabela. • .MYD que contém os dados. • .MYI contendo os índices.

Estas tabelas são de grande desempenho para leitura, uma vez que os seus índices são armazenados em árvores binárias balanceadas, o que provê um ganho para o acesso às informações. O MyISAM não trabalha com transações (commit ou rollback) e também não possui integridade referencial, isto é, ao incluir uma chave estrangeira com alguns constraints, esta servirá apenas como documentação, mas as restrições não serão respeitadas pelo banco.

O tipo InnoDB O tipo InnoDB é do tipo de tabela transacional, desenvolvido pela InnoDBase Oy. A partir da versão 4.0 do MySQL ele passa a ser parte integrante das distribuições do MySQL. O InnoDB apresenta, além da capacidade transacional, outros recursos que são realmente úteis na utilização de tabelas:

• Integridade referencial, com implementação dos constraints SET NULL, SET DEFAULT, RESTRICT e CASCADE; • Ferramenta de backup on-line (ferramenta comercial, não GPL); • Lock de registro, como Oracle, DB2, etc; • Níveis de isolamento; • Armazenamentos de dados em tablespace.

Por se tratar de um tipo de tabela com recursos mais avançados, requer mais espaço em memória e disco, além de se apresentar, em determinadas situações, um pouco mais lento que tabelas do tipo MyISAM. Apesar disto, o tipo InnoDB tem se mostrado extremamente rápido se comparado com outros SGBDs transacionais.

Page 193: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

193193

Alterando o tipo de uma tabela Com o comando ALTER TABLE não é possível alterar o tipo da tabela, por isso, você pode alterar da seguinte maneira: ALTER TABLE departamentos ENGINE=INNODB;

Tipo de dados Como a maioria dos sistemas de gerenciamento de banco de dados relacional (Relational Database Management Systems – RDBMS), o MySQL tem tipos de dados específicos de coluna. O MySQL tem vários tipos de dados que suportam funções diferentes. Um tipo de dados é a definição das informações que uma coluna armazenará. Pode haver muitos tipos de dados em uma tabela, mas cada coluna armazenará seu próprio tipo de informações específicas. Há quatro tipos de grupos de formatos de dados. O primeiro é o numérico. O segundo tipo é o formato de caractere ou string. Esse formato consiste em letras e números ou qualquer coisa que você coloque entre aspas. O terceiro grupo é formado por datas e horas. O tipo final é uma forma de miscelânea. Ele consiste em tudo que não se encaixa em quaisquer uma das outras categorias.

Tipos numéricos Os tipos numéricos destinam-se somente a números. Os diferentes tipos de números ocupam uma quantidade diferente de espaço na memória. Um bom exemplo é você tentando comprar um chocolate em uma loja e ao passar no caixa a você descobre que deve pagar pela caixa inteira. Você diz que não precisa de tudo, mas é atacado e só e vendido de caixa. Se você vai utilizar 3 números, por que ocupar um espaço na memória como se estivesse utilizando 100? Lembre-se: você só deve pagar pelo que vai usar. Tabela B.1 - Armazenamento numérico Nome do tipo Espaço na memória TINYINT 1 byte SMALLINT 2 bytes MEDIUMINT 3 bytes INT 4 bytes BIGINT 8 bytes FLOAT(Inteiro,Decimal) 4 bytes DOUBLE(Inteiro,Decimal) 8 bytes DECIMAL(Inteiro,Decimal) O valor de bytes Inteiro + 2 Se a coluna é numérica e declarada UNSIGNED, o intervalo dobra para o tipo dado. Por exemplo, se você declara que uma coluna que é UNSIGNED TINYINT, o intervalo dessa coluna é de 0 a 255. Declarando dessa forma você faz com que essa coluna tenha somente valores positivos.

Page 194: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

194194

Tabela B.2 -Tipos numéricos Nome do tipo Intervalo de valor Sem sinal TINYINT -128 a 127 0 – 255SMALLINT -32768 a 32767 0 – 65535MEDIUMINT -8388608 a 83888607 0 - 16777215 INT -2147483648 a 2147483647 0 - 4294967295 BIGINT -9223372036854775808 a

92233720368547758070 - 18446744073709550615

FLOAT(Inteiro,Decimal) Varia dependendo dos valores DOUBLE(Inteiro,Decimal) Varia dependendo dos valores DECIMAL(Inteiro,Decimal) Varia dependendo dos valores FLOATs, DOUBLEs e DECIMALs são tipos numéricos que podem armazenar frações. Os outros não. Utilize DECIMAL para números realmente grandes. DECIMALs são armazenados de maneira diferente e não têm limites.

Modificadores AUTO_INCREMENT, UNSIGNED e ZEROFILL Esses modificadores só podem ser utilizados com tipos de dados numéricos. Eles utilizam operações que somente podem ser feitas com números.

AUTO_INCREMENT O modificador de coluna AUTO_INCREMENT automaticamente aumenta o valor de uma coluna adicionando 1 ao valor máximo atual. Ele fornece um contador que é ótimo para criar valores únicos. Você também pode incluir um número. Se quiser que uma coluna AUTO_INCREMENT inicie com 9.000, por exemplo, é só declarar explicitamente um ponto inicial utilizando a seguinte sintaxe: mysql> CREATE TABLE teste ( -> id INT NOT NULL PRIMARY KEY AUTO_INCREMENT -> ) AUTO_INCREMENT=9000;

UNSIGNED UNSIGNED depois de um tipo inteiro significa que ele só pode ter um zero ou valor positivo.

ZEROFILL O modificador de coluna ZEROFILL é utilizado para exibir zeros à esquerda de um número com base na largura de exibição. Como todos os tipos de dados numéricos têm uma largura de exibição opcional, se você declara um INT(8) ZEROFILL e o valor armazenado é 23, ele será exibido como 00000023. Para isso utilize a seguinte sintaxe: CREATE TABLE teste (id INT(4) ZEROFILL);

Page 195: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

195195

Tipos de caractere ou de dados de string O outro grupo importante de tipo de dados são os tipos de strings ou de caractere. Uma string é um conjunto de caracteres. Um tipo de string pode armazenar dados como São Paulo ou Avenida São João, n.º 255. Qualquer valor pode ser armazenado em um tipo de dados de string. Tabela B.3 - Tipos string Nome de tipo Tamanho máximo Espaço de armazenamento CHAR(X) 255 bytes X bytes VARCHAR(X) 255 bytes X + 1 byte TINYTEXT 255 bytes X + 1 byte TINYBLOB 255 bytes X + 2 bytes TEXT 65.535 bytes X + 2 bytes BLOB 65.535 bytes X + 2 bytes MEDIUMTEXT 1,6 MB X + 3 bytes MEDIUMBLOB 1,6 MB X + 3 bytes LONGTEXT 4,2 GB X + 4 bytes LONGBLOB 4,2 GB X + 4 bytes

CHAR e VARCHAR Fora todos esses tipos, os tipos VARCHAR e CHAR são os mais utilizados. A diferença entre eles é que o VARCHAR tem um comprimento variável e o CHAR não. Os tipos CHAR são utilizados para comprimentos fixos. Você utilizará esse tipo quando os valores não variam muito. Se você declara um CHAR(10), todos os valores armazenados nessa coluna terão 10 bytes de comprimento, mesmo se ele tiver 3 bytes de comprimento. O MySQL preenche esse valor para ajustar o tamanho que foi declarado. O tipo VARCHAR faz o contrário. Se você declara um VARCHAR(10) e armazena um valor que tem somente 3 caracteres de comprimento, a quantidade total de espaço de armazenamento é de 4 bytes (o comprimento mais um). A vantagem de utilizar os tipos CHAR é que as tabelas que contêm esses valores fixos são processadas mais rapidamente que aquelas que são compostas pelo tipo VARCHAR. A desvantagem de utilizar o tipo CHAR é o espaço desperdiçado. De um modo geral não se pode utilizar os dois na mesma tabela, pois quando feito o MySQL converte automaticamente uma coluna com o tipo CHAR em VARCHAR. A única exceção é quando você declara uma coluna como VARCHAR(3), o MySQL converte automaticamente em CHAR(3). Isso acontece porque valores de 4 caracteres ou menores são muito pequenos para o tipo VARCHAR.

TEXT e BLOB TEXT e BLOB(Binary Large Object) são tipos variáveis de comprimento que podem armazenar grandes quantidades de dados. Você utilizará esses tipos quando quiser armazenar imagens, sons ou grandes quantidades de textos, como páginas da Web ou documentos. Um bom exemplo é se você estiver querendo armazenar valores de uma <TEXTAREA> de uma sessão de comentários em uma página da Web, o tipo TEXT seria uma boa escolha.

Tipos variados Há basicamente três tipos variados; os tipos ENUM, SET e DATE/TIME.

Page 196: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

196196

Tipo ENUM O tipo ENUM é uma lista ENUMerada. Significa que essa coluna pode armazenar apenas um dos valores que estão declarados na lista dada. Você pode ter até 65.535 itens em sua lista enumerada. É uma boa escolha para caixas de combinação.

Tipo SET O tipo SET é muito parecido com o tipo ENUM. O tipo SET, como o tipo ENUM, armazena uma lista de valores. A diferença é que no tipo SET, você pode escolher mais de uma opção para armazenar. Um tipo SET pode conter até 64 itens. O tipo SET é uma boa escolha para opções em uma página da Web em que o usuário pode escolher mais de um valor.

Tipos de data e hora (DATE/TIME) O MySQL suporta vários tipos de data e hora. Esses são mostrados na tabela a seguir: Tabela B.4 - Tabela de data e hora Tipo Intervalo Descrição DATE 1000-01-01 a 9999-12-31 Datas. Será exibida como YYYY-MM-DDTIME -838:59:59 a 838:59:59 Hora. Será exibida como HH:MM:SS DATETIME 1000-01-01 00:00:00 a

9999-12-31 23:59:59Data e Hora. Será exibida como YYYY-MM-DD HH:MM:SS

TIMESTAMP[(F)] 1970-01-01 00:00:00 Um registro de data/hora, útil para relatório de transação. O formato de exibição depende do formato de F.

YEAR[(2 | 4)] 70-69 (1970-2069)1901-2155

Um ano. Você pode especificar 2 ou 4 formatos de dígitos. Cada um desses tem um intervalo diferente, como mostrado.

Modificadores adicionais de coluna O MySQL tem várias palavras-chave que modificam a maneira como uma coluna funciona. Como vimos acima, temos AUTO_INCREMENT e ZEROFILL e como eles afetam a coluna em que são utilizados. Alguns modificadores se aplicam apenas em colunas de um certo tipo de dado. Tabela B.5 - Tabela de Modificadores Nome de modificador Tipos aplicáveis AUTO_INCREMENT Todos os tipos INT BINARY CHAR, VARCHAR DEFAULT Todos, exceto BLOB, TEXT NOT NULL Todos os tipos NULL Todos os tipos PRIMARY KEY Todos os tipos UNIQUE Todos os tipos UNSIGNED Tipos numéricos ZEROFILL Tipos numéricos O modificador BINARY faz com que os valores armazenados sejam tratados como strings binárias, fazendo-os distinguir letras maiúsculas e minúsculas. Ao classificar ou comparar essas strings, a distinção entre maiúsculas e minúsculas será considerada. Por padrão os tipos CHAR e VARCHAR não são armazenados como binários. O modificador DEFAULT permite especificar o valor de uma coluna se não existir um valor.

Page 197: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

197197

Os modificadores NULL e NOT NULL especifica se na coluna deve haver um valor ou não. Por exemplo; se você especificar a coluna como NOT NULL você é forçado a colocar um valor, pois esse campo é requerido. PRIMARY KEY é um índice que não deve conter valores nulos (NULL). Cada tabela deve conter uma chave primária, isso facilita uma consulta de dados. Abordarei essa questão mais adiante. O modificador UNIQUE impõe a regra que todos os dados dentro da coluna declarada devem ser únicos, mas aceita valores nulos.

Sintaxe básica da SQL A primeira coisa que devemos fazer quando criamos um banco de dados e depois uma tabela e utilizá-la inserindo dados.

Comando INSERT O comando INSERT INTO adiciona dados em uma tabela. A sua sintaxe é: mysql> INSERT INTO departamentos (dept_nome) -> VALUES ('Livros'); O nome da tabela em que você irá inserir deverá ser declarada logo no início INSIRA DENTRO nomedatabela (colunas) VALORES (‘valores inseridos dentro de cada coluna’); É importante salientar que strings ficam entre aspas ou apóstrofos e valores numéricos (declarados como tipo de dados numéricos) não precisam de “aspas” ou ‘apóstrofos’. Para inserir mais de um valor separe-os por vírgula: mysql> INSERT INTO nomedatabela(colunas) VALUES (‘valores inseridos 1’), ->(‘valores inseridos 2’), ->(‘e assim por diante’);

Comando SELECT A instrução SELECT é provavelmente a mais utilizada de todas as instruções de SQL. A instrução SELECT somente retornará os dados que são armazenados no banco de dados dentro de uma tabela. O MySQL realiza essa instrução mais rápido que qualquer outro banco de dados do mercado. A sintaxe é: SELECT nomedacoluna FROM nomedatabela WHERE condições; No caso do nosso banco de dados livraria: SELECT * FROM livros; # o asterisco indica todas as colunas

A cláusula WHERE Com a cláusula WHERE você filtra informações de acordo com a condição passada:

Page 198: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

198198

SELECT * FROM autores WHERE id=3; Nesse caso foi colocada uma condição que dentre todos os registros só deverá aparecer os dados ONDE a coluna id for igual à 3. A cláusula WHERE especifica o critério utilizado para selecionar linhas particulares. O único sinal igual é utilizado para testar igualdade – observe que isso é diferente do Java e é fácil se confundir. Além da igualdade, o MySQL suporta um conjunto completo de operadores e expressões regulares. Na Tabela B.6 a seguir estão listadas as mais utilizadas por você: Tabela B.6 - Tabela de Operadores no MySQL Operador Nome Exemplos Descrição = igual à autor_id = 1 Testa se os dois valores são

iguais> maior que Quantidade > 50 Testa se um valor é maior que

o outro< menor que Quantidade < 50 Testa se um valor é menor que

o outro>= maior ou igual

a Quantidade >= 50 Testa se um valor é maior ou

igual ao outro <= menor ou igual

a Quantidade <= 50 Testa se um valor é menor ou

igual ao outro != ou <> diferente de Quantidade !=0 Testa se um valor é diferente

do outroIN cidade in (‘São Paulo’, ‘Minas Gerais’) Testa se o valor está em um

conjunto particular NOT IN cidade not in (‘São Paulo’, ‘Minas

Gerais’) Testa se o valor não está em um conjunto particular

IS NOT Endereço não é nulo

IS NULL Endereço é nulo

promocao is null Testa se o campo não contém um valor

BETWEEN Quantidade entre um valor e outro

valor BETWEEN 200 AND 350 Testa se o campo tem valores entre um e outro

Funções que trabalham com a instrução SELECT Vistas ao longo desse livro, sejam aplicadas ou comentadas, você tem a explicação mais detalhada a seguir:

LIMIT Função que limita resultados exibidos na tela. SELECT * FROM tabela LIMIT 2; Limita a visualização de 2 linhas de dados. SELECT * FROM tabela LIMIT 2,5; Limita a visualização da linha 2 a linha 5 de dados. Esta instrução foi utilizada para paginação de dados.

Page 199: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

199199

COUNT( ) Conta a quantidade de linhas encontradas, de acordo com a coluna passada entre os parênteses. Para contar uma determinada quantidade de dados em uma coluna: SELECT COUNT(coluna) FROM tabela; Isso não reflete a quantidade total existente na tabela, pois um valor NULL pode existir. Para contar o total de linhas existentes em uma tabela, use: SELECT COUNT(*) FROM tabela; Conta quantas linhas de dados existem em todas as linhas. Nota: Em caso de fazer a contagem em campo de valor NULL, o resultado final será diferente.

ORDER BY Ordena os resultados de acordo com a coluna estabelecida (crescente ou decrescente): SELECT * FROM tabela ORDER BY coluna; Ordena de forma crescente pela coluna dada.

ORDER BY ... DESC  SELECT * FROM tabela ORDER BY coluna DESC; Coloca os dados selecionados em ordem decrescente pela coluna.

LIKE Usado para filtrar dados em uma coluna que armazena strings (varchar, text e etc…). Sua sintaxe é como mostrada a seguir: mysql>SELECT * FROM autores WHERE nome LIKE 'ed%'; Neste caso pode-se fazer uma busca por apenas a inicial do valor desejado. O sinal de %(porcentagem) é o caractere curinga que significa qualquer caractere. mysql>SELECT * FROM livros WHERE nome LIKE '%dominando%'; Colocando a % no início e no fim, com um valor no meio, é possível buscar todos os valores que contenham a palavra dominando, seja no começo, meio ou fim. Esta instrução foi feita para os exemplos que utilizavam um sistema de auto-completar (caixa de sugestões).

Page 200: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

200200

Comando UPDATE O comando UPDATE permite editar os valores de dados existentes. A sintaxe para modificar os valores é: UPDATE tabela SET coluna= ‘valor’ WHERE coluna=’valor’; Atualiza os dados da coluna determinada em SET na condição passada em WHERE.

Comando DELETE A instrução DELETE é muito semelhante á instrução SELECT. A única diferença em vez de selecionar registros para visualizar, essa instrução exclui esses registros. A instrução DELETE tem a seguinte sintaxe: DELETE FROM tabela WHERE coluna=’valor’;

Trabalhando com Junções As junções são uma parte integrante de um banco de dados relacional. As junções permitem ao usuário de banco de dados tirar proveito dos relacionamentos que foram desenvolvidos na fase do projeto do banco de dados. Uma JUNÇÃO é o termo utilizado para descrever o ato em que uma ou mais tabelas são “unidas” entre si para recuperar dados necessários com base nos relacionamentos que são compartilhados entre elas.

Criando uma junção com INNER JOIN A seguinte sintaxe cria uma junção: SELECT tabela1.coluna, tabela2.coluna FROM tabela1 INNER JOIN tabela2 on tabela1.coluna_de_valor_identico=tabela2.coluna_de_valor_identico; INNER JOIN’s são provavelmente as mais comuns de todas as junções. Uma INNER JOIN significa que todos que todos os registros que estão sem correspondência são descartados. Somente as linhas correspondidas serão exibidas no conjunto de resultados. Os dados aparecem na ordem em que você especifica.

Chaves variadas do MySQL 

O que é uma chave? Uma chave em uma tabela em um banco de dados fornece um meio de localizar rapidamente informações específicas. Embora uma chave não precise significar qualquer coisa para o usuário humano do banco de dados, as chaves são uma parte vital da arquitetura de banco de dados e pode influenciar significativamente o desempenho.

Como as chaves funcionam Uma chave existe como uma tabela extra no banco de dados, embora pertença à sua tabela pai. Ela ocupa espaço físico no disco rígido (ou outras áreas de armazenamento) do banco de dados. Pode ser tão grande quanto a tabela principal e, teoricamente, até maior.

Page 201: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

201201

Você define a chave para se relacionar com uma ou várias colunas em uma tabela específica. Como os dados em uma chave são totalmente derivados da tabela, você pode eliminar e recriar uma chave sem qualquer perda de dados.

Benefícios de usar uma chave A utilização adequada de chaves pode aprimorar significativamente o desempenho do banco de dados. Para utilizar a analogia de um índice de livro, considere o pouco número de páginas que é necessário no índice de um livro para dar visão rápida dos temas importantes. Compare quanto tempo você levaria se estivesse pesquisando pelo volume, página por página.

Suporte de chaves do MySQL O MySQL suporta os seguintes comandos para criar chaves nas tabelas existentes: ALTER TABLE nome_tabela ADD (KEY | INDEX) nome_do_índice (nome_da_coluna [,...]); ALTER TABLE nome_tabela ADD UNIQUE nome_do_índice (nome_da_coluna[,...]); ALTER TABLE nome_tabela ADD PRIMARY KEY nome_do_índice (nome_da_coluna[,...]); Observe que no MySQL, chave e índice são sinônimos. Esses são os formatos preferidos para adicionar chaves a tabelas existentes. Para compatibilidade com outras implementações de SQL, o MySQL também suporta os seguintes: CREATE INDEX nome_do_índice ON nome_tabela (nome_da_coluna[,...]); CREATE UNIQUE INDEX [nome_do_índice] ON nome_tabela (nome_da_coluna[,...]); CREATE PRIMARY KEY ON nome_tabela (nome_da_coluna,...); Você pode definir as chaves quando cria uma tabela: CREATE TABLE nome_da_tabela (nome_da_coluna tipo_de_campo [NULL | NOT NULL], KEY col_index (nome_da_coluna));

Chaves primárias (Primary Key) Uma chave primária é semelhante em princípio a uma chave única, seus dados devem ser únicos, mas a chave primária de uma tabela tem um status mais privilegiado. Apenas uma chave primária pode existir para cada tabela e seus valores de campo nunca podem ser nulos. Uma chave primária é geralmente utilizada como um link estrutural no banco de dados, definindo o relacionamento entre as tabelas diferentes. Sempre que quiser unir uma tabela a outra, você deve ter a chave primária dessa tabela. O MySQL não requer que você especifique que a coluna em que estiver a chave primária seja NOT NULL(não nula) *, mas porém se tentar colocar um valor idêntico na coluna chave, esta retornará um erro que não pode haver duplicação.

Page 202: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

202202

* Este caso é somente para chaves primárias em tabelas cuja coluna selecionada seja INT ou semelhante. Em casos de ser VARCHAR, CHAR e etc, é exigida a utilização do NOT NULL. Caso isso não ocorra, você terá como resultado um erro. Se desejar que seja nulo o campo, coloque uma chave UNIQUE.

Chaves estrangeiras (Foreign Key) As chaves estrangeiras não são atualmente suportadas no MySQL pelas tabelas do tipo MyIsam. A mais usada e recomenda para transações são as tabelas do tipo InnoDB. A seguir você tem o comando necessário para criar uma chave estrangeira no seu banco de dados: ALTER TABLE produtos ADD CONSTRAINT fk_categoria FOREIGN KEY (CategoriaID) REFERENCES categorias (CategoriaID) ON DELETE CASCADE ON UPDATE CASCADE;

Excluindo uma chave estrangeira Para excluir uma chave estrangeira, use o comando: ALTER TABLE produtos DROP FOREIGN KEY fk_ categoria;

Administrando o MySQL Um sistema de MySQL pode ter muitos usuários. O usuário root geralmente deve ser utilizado somente para propósitos de administração, por razões de segurança. Para cada usuário que precisar utilizar o sistema, você precisará configurar uma conta e senha. Não é obrigatório configurar senhas para usuários, mas recomendo que você configure senhas para todos os usuários que forem criados.

Entendendo o sistema de privilégios do MySQL O MySQL suporta um sofisticado sistema de privilégios. Um privilégio é um direito que um usuário tem para realizar uma ação particular em um objeto particular. Quando você cria um usuário no MySQL, você concede a ele um conjunto de privilégios para especificar o que ele pode e não pode fazer dentro do sistema.

Configurando usuários Os comandos GRANT e REVOKE são utilizados para fornecer e retirar direitos dos usuários do MySQL. Ele pode ser concedido nos seguintes níveis: • Global • Banco de dados • Tabela • Coluna O comando para criar um usuário com privilégios é como mostrado a seguir: GRANT privilégios [colunas] ON item TO nome_do_usuario [IDENTIFIED BY ‘senha’] [WITH GRANT OPTION]

Page 203: Netbeans 6 - livro

Desenvolvendo Aplicações Web com NetBeans IDE 6

Parte integrante do livro Desenvolvendo Aplicações Web com NetBeans IDE 6 – não pode ser vendido ou distribuído separadamente

203203

As cláusulas entre colchetes são opcionais. Para conceder privilégios ao um usuário no banco livraria, você deve criar um usuário com os seguintes privilégios: mysql> grant all -> on livraria.* -> to edson identified by 'integrator'; Com isso você concede todos os privilégios de manipulação do banco de dados livraria somente ao usuário edson, com a senha integrator.

Confirmando o novo usuário Para confirmar a criação do novo usuário, você deve executar o comando a seguir: flush privileges;

Revogando privilégios Para revogar esse privilégio você deve fazer o seguinte comando: mysql> revoke all -> on relatorios.* -> from edson;

Obtendo informações com SHOW Se você desejar visualizar todos os privilégios que um usuário tem, execute o seguinte comando: SHOW GRANTS FOR edson; Para visualizar todos os usuários existentes no seu MySQL execute; SHOW GRANTS;