Relatórios avançados com Hibernate, JasperReports e PrimeFaces – Parte 1

Desenvolva relatórios com virtualização e paginação utilizando Hibernate e JasperReports.

Artigo no estilo: Curso
Fique por dentro
Segundo estudos elaborados pela IDC, uma empresa de consultoria para indústrias de TI, a quantidade de informação dobra a cada dois anos no mundo e com esse crescimento, os sistemas são submetidos a processar quantidades cada vez maiores de dados. Para lidar com essa questão, foram criadas diversas tecnologias/técnicas focadas no aumento da eficiência do gerenciamento de memória. Com base nisso, abordaremos neste artigo algumas dessas técnicas, como a virtualização e a paginação da memória heap em aplicações escritas em Java, com ênfase na geração de relatórios que acessam grandes quantidades de dados. Dessa forma o leitor terá uma referência do que fazer ao se deparar com situações semelhantes.

A tomada de decisões nas empresas de hoje está completamente atrelada à disponibilização de relatórios por seus sistemas. No entanto, como a linguagem Java não possui suporte nativo a tal recurso, precisamos de mecanismos externos que supram essa carência.

Surgiu assim o JasperReports, uma biblioteca open source escrita em Java focada exatamente na simplificação da construção de relatórios para aplicações desenvolvidas com a mesma linguagem. Apesar de seu sucesso hoje em dia, as primeiras versões do JasperReports eram bastante improdutivas, pois exigiam o domínio do seu DTD (Document Type Definition), um documento descritor XML utilizado pelo JasperReports para gerar os relatórios. O desenvolvedor tinha que escrever seu código num editor de textos qualquer, pois não existia uma ferramenta que abstraísse esse trabalho. Na Listagem 1 apresentamos um exemplo de como declarar um label no DTD. Como pode ser observado, não é nada trivial e de fácil leitura.

Listagem 1. Exemplo de código do arquivo DTD. 01 <staticText> 02 <reportElement x="0" y="0" width="117" height="35"/> 03 <box leftPadding="2"/> 04 <textElement verticalAlignment="Middle"> 05 <font isBold="true"/> 06 </textElement> 07 <text><![CDATA[Descrição]]></text> 08 </staticText>

O intervalo entre as linhas 1 e 8 define um texto estático, um label. Na linha 2 os atributos x e y configuram as coordenadas do posicionamento do elemento no relatório e width e height definem sua área delimitadora. Em seguida, na linha 3, definimos a margem esquerda interna do texto dentro de sua região. Das linhas 4 a 6 especificamos a formatação do elemento de texto, que no caso será exibido em negrito. Finalmente, na linha 7 adicionamos o conteúdo que será apresentado no relatório, pela label: o texto “Descrição”.

Constatada essa dificuldade, o iReport foi criado. Como já esperado, seu objetivo é facilitar o desenvolvimento de relatórios, tornando transparente o conhecimento sobre como estruturar o arquivo DTD, o que se dá com a automatização do processo de escrita desse arquivo.

Com o iReport podemos projetar relatórios através de uma interface gráfica que disponibiliza diversas opções para criar layouts complexos e de maneira simples. Esta ferramenta possibilita também utilizar recursos avançados do JasperReports que podem auxiliar em situações específicas como, por exemplo, a virtualização da memória heap, que permite fazer swap em disco. Esta técnica faz com que pequenas porções da memória heap sejam escritas diretamente no disco, tornando possível seu gerenciamento. A virtualização é recomendada quando processamos uma grande quantidade de informações e temos pouca memória heap disponível, o que pode ocasionar erros do tipo OutOfMemoryException.

Outro recurso muito interessante que pode ser implementado com o auxílio do JasperReports e que ajuda no gerenciamento da memória é a paginação. No entanto, a paginação não é um recurso nativo desta biblioteca, tendo que ser implementada à parte. Veremos como fazer isso mais adiante.

Uma vez que o nosso foco será a demonstração de recursos mais avançados do iReport e do JasperReports, este artigo pressupõe que o leitor já tenha noções básicas destas ferramentas. Caso queira adquirir tais conhecimentos, recomendamos a leitura do artigo “Gerando Relatórios com JasperReports”, publicado na Edição 19 da Easy Java Magazine.

Dito isso, para demonstrar a virtualização e a técnica de paginação, apresentaremos um exemplo desses recursos na prática a partir da construção de um pequeno simulador genérico de perguntas e respostas que utiliza o Tomcat como container web, o Hibernate para acessar a base de dados MySQL e o PrimeFaces para construir a interface gráfica.

O PrimeFaces

O PrimeFaces é considerado a biblioteca mais completa de componentes ricos para aplicações web ou mobile escritas em Java. Devendo ser utilizada junto com o JavaServer Faces (JSF), foi uma das primeiras soluções RIA a estar totalmente convertida para funcionar com o JSF na versão 2.0.

Lançada em 2008 pela PrimeTek, o PrimeFaces traz como uma das suas principais vantagens uma comunidade bastante ativa, onde problemas comuns são relatados e solucionados de forma interativa. A biblioteca tem seu código aberto e é muito bem documentada, disponibilizando versões gratuitas e com várias opções de componentes de interface.

As aplicações RIA têm como particularidade oferecer recursos ricos de interface, como formas de arrastar e soltar objetos na tela, atualização de dados sem recarregamento da página, animações e um visual diferenciado. Devido a isso, construir uma solução RIA era extremamente complexo, pois além de exigir conhecimentos em diferentes tecnologias, tornava o desenvolvimento bastante improdutivo, ao obrigar o desenvolvedor a implementar todas as rotinas necessárias para o seu funcionamento.

A proposta do PrimeFaces é auxiliar na resolução dos problemas proporcionados pela utilização dos componentes ricos de interface, resolvendo questões como a necessidade de adquirir conhecimentos em várias linguagens de programação e a alta complexidade na construção das rotinas de funcionamento de tais componentes. Essa facilidade é provida pelo framework através da disponibilização de componentes que englobam as funcionalidades dos recursos RIA, de modo que o desenvolvedor não precisa se preocupar com detalhes da sua implementação. Com isso, ganhamos na produtividade, pois ao utilizá-lo diminuímos o tempo no desenvolvimento das funcionalidades e melhoramos também a qualidade do software, por conta da adoção de códigos padronizados e já testados pela equipe do PrimeFaces.

Com base nisso, demonstraremos como utilizar alguns dos seus componentes no decorrer da construção do simulador aqui proposto e, à medida que adicionarmos tais componentes, notaremos a facilidade com que ele lida com os recursos característicos do RIA comentados anteriormente.

O Hibernate

Ao utilizar bancos de dados relacionais em aplicações Java, nos deparamos com um problema conhecido como impedância, que é a incompatibilidade entre o modelo relacional e o modelo orientado a objetos. Esta incompatibilidade ocorre devido ao paradigma orientado a objetos ser baseado nos princípios da engenharia de software, ao passo que o paradigma relacional é fundamentado nos princípios matemáticos da álgebra relacional.

Uma solução para o problema da impedância é a utilização de bibliotecas ORM (Object Relational Mapping), que são responsáveis pelo mapeamento entre as classes Java e as tabelas do banco, deixando esse trabalho totalmente transparente para o desenvolvedor.

O Hibernate é a solução ORM para aplicações Java mais utilizada do mercado e traz como principais vantagens: ser um framework não intrusivo, ou seja, a arquitetura da aplicação permanece independente; ter uma comunidade bastante ativa; e ser muito bem documentado. Para seu correto funcionamento, ele precisa de metadados, isto é, informações inseridas nas classes (ou em arquivos de configuração) que são necessárias ao mapeamento para interligar elementos do modelo orientado a objetos a elementos do modelo relacional. Na versão 3.5.0, versão adotada no simulador, utilizamos anotações para mapear os relacionamentos do sistema como, por exemplo, @OneToMany, que define um relacionamento de um para muitos entre duas entidades, e @ManyToMany, que define um relacionamento de muitos para muitos. Em versões anteriores à 3, os mapeamentos eram realizados através de um arquivo XML, conhecido como hibernate.cfg.

Ainda neste artigo, demonstraremos como configurar um recurso do Hibernate responsável por exportar todo o esquema de criação do banco de dados de forma automática. Ao utilizar esse recurso, nos preocupamos apenas em anotar corretamente as propriedades das classes para que o próprio Hibernate se encarregue com a administração da estrutura do banco de dados. Desta forma, nos concentramos apenas com as regras de negócio e o layout da aplicação." [...] continue lendo...

Artigos relacionados