Atenção: esse artigo tem um vídeo complementar. Clique e assista!

De que se trata o artigo:

O artigo apresenta a criação de uma aplicação Java EE 6 completa que utiliza o MongoDB como mecanismo de persistência. No decorrer do artigo, são também mostradas dicas para modelagem de dados no MongoDB, além de boas práticas de uso das API Java EE e de modularização de aplicações. O MongoDB é o banco de dados NoSQL (Not only SQL) mais conhecido atualmente, fornecendo uma alternativa robusta e viável aos tradicionais banco de dados relacionais.

Em que situação o tema é útil:

O modelo relacional, utilizado nos SGBDs atuais, é bem conhecido e dominado por grande parte da indústria. Todavia, frente à nova era das aplicações feitas para a Internet, massivamente escaláveis e com um volume absurdo de dados, suas já conhecidas limitações tem se tornado grandes obstáculos, o que por sua vez tem incentivado a pesquisa e o desenvolvimento de formas alternativas de armazenamento de dados estruturados, tais como o MongoDB. O conhecimento da arquitetura e o uso deste banco são essenciais neste momento, tornando-se uma importante ferramenta para arquitetos e desenvolvedores envolvidos em novos projetos.

Resumo DevMan:

O MongoDB é um banco de dados NoSQL orientado a documentos. Documentos são estruturas análogas a objetos JSON e constituem a unidade básica de armazenamento do MongoDB. Um conjunto de documentos que representam entidades similares é agrupado em coleções, que podem ser comparadas ao conceito de tabelas do modelo relacional. O driver do MongoDB fornece uma API simples para interação com o banco e pode ser facilmente utilizada em uma aplicação Java EE, substituindo (ou complementando) um mecanismo de persistência tradicional.

Autores: Paulo Sigrist e Wilson Akio Higashino

NoSQL é um termo, relativamente recente, que tem aparecido com frequência na agenda de desenvolvedores e arquitetos de soluções. Embora ainda não tenha uma definição precisa, o termo é usado para classificar um conjunto de ferramentas de armazenamento de dados que possuem um modelo de dados diferente do tradicional modelo relacional, e/ou que se diferenciam dele em algum aspecto arquitetural, tal como no modelo de consistência, de distribuição ou de linguagem para manipulação de dados. Tal termo também é utilizado para falar sobre uma “corrente” de arquitetura, que prega uma análise mais profunda das necessidades de persistência das aplicações e o uso das ferramentas citadas complementando os tradicionais SGBDs relacionais. Este aspecto complementar é enfatizado pelo significado da sigla ser “Not Only SQL” (Não Somente SQL) – ao contrário do sugerido por um contato inicial (Não SQL).

Em edições anteriores da revista, o tema NoSQL foi abordado em uma série de artigos de Alexandre Porcelli, um dos maiores especialistas do assunto no Brasil, no qual apresentou-se os principais conceitos e paradigmas relacionados ao tema, as ferramentas mais utilizados e como escolher entre as diversas opções disponíveis.

Este artigo explora em maior profundidade um dos bancos NoSQL mais comentados e utilizados atualmente: o MongoDB (de humongous, gíria americana que significa extraordinariamente grande). Para tal, construímos uma aplicação exemplo baseada nos mais recentes padrões do Java EE 6, tais como JSF 2.0, CDI 1.0 e EJB 3.1, e implementamos a persistência através do MongoDB.

A aplicação consiste em um player de músicas acessado através da web, com recursos de redes sociais para compartilhamento de opiniões. Através desse rico estudo de caso, exemplificamos como a modelagem orientada a documentos, utilizada pelo Mongo, difere da tradicional modelagem entidade-relacional. Mostramos também como interagir com o MongoDB através do driver Java, além de ilustrar técnicas de construção de aplicações e boas práticas das APIs Java EE quando utilizadas em conjunto. Por fim, exploramos recursos avançados disponíveis na plataforma, tais como a injeção de dependências e a implementação do padrão Observer disponíveis no CDI, o uso de mensagens assíncronas através do JMS e chamadas Ajax na camada de apresentação.

Como veremos, o MongoDB oferece uma boa alternativa para a persistência de dados, provendo facilidades para um desenvolvimento altamente produtivo e um produto final de ótimo desempenho. Esperamos com isso incentivar o leitor ao seu uso e ao estudo de outras ferramentas NoSQL, ampliando o seu leque de opções e ajudando-o a fazer as escolhas mais adequadas de ferramentas de armazenamento de dados.

Aplicação exemplo

A aplicação a ser construída é um player de músicas online, acessado pela Web, com recursos de redes sociais para compartilhamento de opiniões e notas, e um mecanismo automatizado para inserção de novas músicas no repositório.

Algumas das funcionalidades que estão disponíveis para o usuário são:

· Criação de Playlists: o usuário pode criar listas de execuções com suas músicas preferidas. No momento da criação, ele busca as músicas cadastradas no sistema através do nome e as adiciona à lista;

· Escutar Playlists: o usuário tem a disposição um player de música, em que ele seleciona uma playlist anteriormente criada para tocar. Neste momento, ele pode também comentar sobre as músicas e avaliá-las, além de visualizar os comentários e notas de outros;

· Inserir Músicas: o processo de inserção de novas músicas no repositório da aplicação é feito através de um processo de indexação de diretórios. O usuário aponta um diretório e a aplicação encarrega-se de ler todas as músicas no formato MP3, cadastrando-as automaticamente.

Como todo serviço de sucesso, essa aplicação possui também alguns requisitos extras que precisam ser atendidos:

· Tempo muito pequeno para seu lançamento inicial;

· Preparação para explosão, a qualquer momento, no número de usuários;

· Adição de funcionalidades constantes e não disruptivas.

Analisando-se estas características, além da necessidade de bom desempenho para pequenas (e muitas) leituras e escritas e a expectativa da geração de grande volume de dados, o MongoDB torna-se um bom candidato para implementação da persistência da aplicação.

Preparando o ambiente

Para a execução da aplicação, iremos precisar de um servidor de aplicações Java EE 6 e um servidor de banco de dados MongoDB. O servidor Java EE 6 utilizado foi o GlassFish 3.1, mas não deve haver problemas com outros servidores.

Configurando o GlassFish

O processo de instalação do GlassFish pode ser consultado em seu próprio site (ver seção Links [2]). Adicionalmente, é necessária a criação de uma fila JMS no servidor. Como veremos a frente, ela é necessária para a comunicação assíncrona e fracamente acoplada entre dois módulos da aplicação.

Podemos criar esse recurso diretamente pela interface de administração do GlassFish ou podemos utilizar a ferramenta de linha de comando asadmin. Para utilizar essa ferramenta, o primeiro passo é criar um arquivo de configuração com os recursos que serão adicionados. Assim, crie um arquivo chamado glassfish-resources.xml em uma pasta de sua preferência com o conteúdo da Listagem 1.

Listagem 1. Arquivo de configuração de recursos para o GlassFish – glassfish-resources.xml.

<?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE resources
    PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" 
    "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
   
  <resources>
      <connector-connection-pool name="musicIndexerConnectionFactory"
            resource-adapter-name="jmsra" 
            connection-definition-name="javax.jms.QueueConnectionFactory" />
      <connector-resource pool-name="musicIndexerConnectionFactory"
            jndi-name="musicIndexerConnectionFactory" />
      <admin-object-resource res-adapter="jmsra"
            res-type="javax.jms.Queue" jndi-name="queue/musicIndexerQueue">
        <property name="Name" value="musicIndexerQueue" />
      </admin-object-resource>
  </resources>

O próximo passo é adicionar esses recursos no servidor de aplicação. Para tal, abra um console e execute o seguinte comando:

$ cd <GLASSFISH_HOME>/glassfish/domains/domain1/bin
  $ asadmin add-resources <PASTA_DO_ARQUIVO>/glassfish-resources.xml

A correta execução do comando deverá resultar em:

Command : Connector connection pool musicIndexerConnectionFactory created.
  Command : Connector resource musicIndexerConnectionFactory created.
  Command : Administered object queue/musicIndexerQueue created.
  Command add-resources executed successfully.

Após a conclusão desse passo, os recursos necessários para a nossa aplicação estarão devidamente configurados no servidor de aplicações.

Instalando o MongoDB

Utilizamos neste artigo a versão 1.8.2 do MongoDB. Para instalá-lo, acesse a sua página (ver seção Links [1]) e faça o download de acordo com o ambiente e arquitetura (32 ou 64 bits) em que ele irá executar. Após o término do download, descompacte o arquivo em uma pasta de sua preferência e ele estará pronto para utilização. Use o seguinte comando no console para iniciar o servidor:

$ cd <MONGODB_HOME>/bin
  $ mongod --dbpath <PASTA_BD>

O parâmetro --dbpath especifica o diretório que o MongoDB utiliza para armazenar a sua base de dados. Se tudo correr bem, mensagens semelhantes às seguintes serão mostradas:

Sun Sep 11 12:14:56 [initandlisten] MongoDB starting : pid=5240 port=27017 dbpath=c:\database 64-bit
  Sun Sep 11 12:14:56 [initandlisten] db version v1.8.2, pdfile version 4.5
  Sun Sep 11 12:14:56 [initandlisten] git version: 433bbaa14aaba6860da15bd4de8edf600f56501b
  Sun Sep 11 12:14:56 [initandlisten] build sys info: windows (6, 1, 7600, 2, '')BOOST_LIB_VERSION=1_42
  Sun Sep 11 12:14:56 [initandlisten] waiting for connections on port 27017
  Sun Sep 11 12:14:56 [websvr] web admin interface listening on port 28017

A fim de verificar o funcionamento do MongoDB, você pode conectar-se a ele utilizando o comando mongo no diretório <MONGODB_HOME>/bin. Este comando executa a shell da ferramenta, que por padrão conecta-se a base de dados de nome test.

$ ./mongo
  MongoDB shell version: 1.8.2
  connecting to: test

Um fato interessante é que esta shell aceita qualquer comando JavaScript válido. Assim, podemos criar um primeiro documento utilizando a sintaxe JavaScript para definição de objetos JSON:

> x = {nome : "Wilson", idade : 99 }

Tudo que está entre as chaves representa um único documento. Um documento, por sua vez, é composto por um conjunto de atributos, que são definidos separados por vírgulas na forma de pares nome:valor. No MongoDB, esses documentos constituem a unidade básica de armazenamento.

Podemos inserir o documento x em uma coleção de nome nomes utilizando:

> db.nomes.insert(x)

Para verificar se a inserção foi corretamente realizada, executamos uma consulta na mesma coleção:

> db.nomes.find()

O que deve retornar algo como:

{ "_id" : ObjectId("4e6eb264a7d31fef3583d14d"), "nome" : "Wilson", "idade" : 99 }

Observe que _id não foi definido explicitamente em x, mas foi retornado. Este atributo foi gerado automaticamente e representa um identificador único para o documento recém-inserido. Note também que em nenhum momento precisamos definir a estrutura da coleção nomes e nem criá-la explicitamente. Outro ponto interessante é que, em uma mesma coleção, podemos ter documentos com estruturas diferentes. Esta flexibilidade é um dos pontos fortes do Mongo, como perceberemos no decorrer do artigo.

Estrutura da aplicação

Com os objetivos prover uma clara separação de responsabilidades e aumentar o grau de reuso das funcionalidades, a aplicação foi dividida em três componentes principais: musiclib-indexer, musiclib-model e musiclib-web. No primeiro deles, temos as classes necessárias para indexar os arquivos MP3. O segundo contém as classes de negócios, as implementações de serviços e o código que interage com o MongoDB. O último componente, por sua vez, contém o projeto Web. Temos também o projeto musiclib-ear, utilizado para empacotar todos os módulos em um único arquivo EAR (Enterprise Archive) e facilitar a distribuição da aplicação.

A Figura 1 mostra a estrutura de diretórios da aplicação, que pode ser baixado do site da revista ou do próprio controle de versões do projeto (seção Links [3]).

Figura 1. Estrutura de diretórios do projeto.

Para auxiliar o processo de compilação e montagem, o projeto foi estruturado como um projeto multimódulo, fazendo com que o Maven trate todos os componentes como pertencentes a um mesmo processo de construção. Desta maneira, a ferramenta consegue determinar a ordem correta da compilação baseada nas dependências que existem entre esses componentes. Foi criado também um arquivo POM pai, do qual todos os outros arquivos POM herdam. Nesses arquivos estão declaradas as dependências do projeto, que são:

...

Quer ler esse conteúdo completo? Tenha acesso completo