Criando uma aplicação com JSR-371(MVC 1.0)

Neste artigo criaremos um aplicação simples para demostrar o uso da API MVC 1.0 (JSR 371) do JEE 8 juntamente com MongoDB.

Boa Leitura.

mvc1-0capa

Introdução ao MVC 1.0

MVC é um padrão comum em frameworks web, onde este é usado predominantemente para criar aplicativos HTML. Frameworks web podem ser categorizados c0mo Action-Based ou Component-Based. Em Action-Based, as solicitações HTTP são encaminhadas para controladores onde elas são transformadas em ações pelo código da aplicação. Em Component-Based, as solicitações HTTP são agrupadas e normalmente tratadas por framework de Componente, com pouca ou nenhuma interação do código da aplicação. Em outras palavras, um framework baseado em componentes, a maioria da sua lógica do controle é fornecida pelo framework em vez da aplicação.

Esta API se enquadra na categoria Action-Based, ela não se destina a substituição de frameworks baseado em componentes como a JSF, mas simplesmente uma alternativa para a construção de aplicações web para a plataforma Java EE.

Os Objetivos da API:

De acordo com a sua especificação está api propõe os seguintes objetivos:

  • Aproveitar as tecnologias Java EE existentes.
  • Integrar com CDI e Bean Validation
  • Definir um núcleo solido para construir aplicações MVC sem a necessidade suportar todas as funcionalidade em sua primeira versão.
  • Explora as camada em cima do JAX-RS com a finalidade de reutilizar suas camadas de Matching e binding.
  • Fornece suporte interno para JSP e Facelets.

Não são Objetivos da API:

  • Definir uma nova linguagem de visualização(template) e processador.
  • Suporte a serviços REST não baseads em JAX-RS.
  • Suporte a implementação autonoma do MVC executado fora do Java EE.
  • Fornecer suporte interno para views que não fazem parte do Java EE.

Criando o Projeto

Antes de inciarmos a criação do projeto devemos fazer o download do servidor de Aplicação para que o mesmo funcione. Porém até o momento ela funciona com uma versão especifica do GlassFish que pode ser baixada no seguinte link : http://download.oracle.com/glassfish/4.1/nightly/glassfish-4.1-b17-09_15_2015.zip .   Feito isso, podemos da inicio.

Com o Eclipse aberto, vá File -> New – > Maven Project irá abrir a seguinte Janela :

maven

 clique em Next para ir para a seguinte tela :

maven2

    clique em Next, na próxima deixe preenchida da seguinte forma  e clique em Finish:

mvc1

com o projeto criado,vá em src/main/webapp, nela apague a pasta WEB-INF. Depois clique com o botão direito do mouse e vá em Properties, navegue até a opção Targeted Runtimes, marque a opção, que no caso vamos utilizar o GlassFish, depois clique em Uninstall Facets… :

mvc2

mvc3

ao chegar nesta tela desmaque Dynamic Web Module , altere Java 1.5 para 1.8,marque CDI,Glassfish Web Extensions e JAX-RS e clique em Finish. Abra novamente a mesma tela e maque Dynamic Web Module e mude de 2.3 para 3.1 e clique em Next para configura a proxima tela e a configure como abaixo :

mvc5

Clique em Finish e depois em OK.

Agora iremos configurar nosso pom.xml, com a seguinte configurações :

<project 
xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>br.com.danieldias</groupId>
  <artifactId>MVC1.0.Ozark</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>MVC1.0.Ozark Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
			<groupId>javax</groupId>
			<artifactId>javaee-web-api</artifactId>
			<version>7.0</version>
			<scope>provided</scope>
		</dependency>

	<!-- Mongo Driver -->
		<dependency>
			<groupId>org.mongodb</groupId>
			<artifactId>mongodb-driver</artifactId>
			<version>3.4.1</version>
		</dependency>
		
		<dependency>
            <groupId>org.glassfish.ozark</groupId>
            <artifactId>ozark</artifactId>
            <version>1.0.0-m02</version>
            <scope>compile</scope>
        </dependency>
        
         <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        
        <dependency>
			<groupId>org.glassfish.jersey.core</groupId>
			<artifactId>jersey-server</artifactId>
			<version>2.22</version>
		</dependency>
  </dependencies>
  <build>
    <finalName>MVC1.0.Ozark</finalName>
    		<plugins>
    		   <plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.5</version>
				<configuration>
					<failOnMissingWebXml>false</failOnMissingWebXml>
				</configuration>
			</plugin>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.5.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
  </build>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>
</project>


 Na pasta WEB-INF , configure o beans.xml do CDI da seguinte forma :

<?xml version="1.0" encoding="UTF-8"?>
<beans 
xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://xmlns.jcp.org/xml/ns/javaee 
 http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
</beans>

Ainda dentro de WEB-INF também crie uma pasta chamada views.
Depois clique em cima do projeto e de “Alt +F5” para fazer update do maven :

mvc6

Clique em OK e finalizamos a parte de criação projeto, podemos da inicio a codificação de nossas classes .

Criando a Constantes.java

Está classe é bem simples, ela irá somente conter valores constantes, que não serão modificadas. Isso para evitar ter muitas hardCode espalhado por todo o código, assim esse classe irá centralizar tudo de maneira organizada.

Crie uma classe chamada Constantes no package br.com.danieldias.commons, com o seguinte conteúdo :

package br.com.danieldias.commons;

/**
 * @author daniel
 * github:Daniel-Dos
 * daniel.dias.analistati@gmail.com
 * twitter:@danieldiasjava
 */
public class Constantes {

	/*Nome o Banco e da Collection*/
	public static final String BANCO_NOME = "danieldiasjava";
	public static final String COLLECTION_NOME = "pessoas";

	/*Nomes das Colunas para o MongoDB*/
	public static final String NOME = "nome";
	public static final String IDADE = "idade";
	public static final String ENDERECO = "endereco";
	public static final String ESTADO = "estado";
	public static final String JUGS = "jugs";
	public static final String DESCRICAO = "descricao";
	public static final String ID = "_id";
}

Criando as Entidades

Crie as classes Pessoa.java e Endereco.java no package br.com.danieldias.model , com o seguinte conteúdo :

package br.com.danieldias.model;

import javax.ws.rs.FormParam;

import org.bson.types.ObjectId;

/**
 * @author daniel
 * github:Daniel-Dos
 * daniel.dias.analistati@gmail.com
 * twitter:@danieldiasjava
 */
public class Pessoa {

	@FormParam("_id")
	private ObjectId _id;

	@FormParam("nome")
	private String nome;

	@FormParam("idade")
	private int idade;

	@FormParam("endereco")
	private Endereco endereco;

	@FormParam("jugs")
	private String jugs;

	@FormParam("descricao")
	private String descricao;

	public String getDescricao() {
		return descricao;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}

	public Pessoa() {
	}

	public Pessoa(String nome, Endereco endereco,
			String descricao,int idade,
			String jugs) {
		super();
		this.nome = nome;
		this.endereco = endereco;
		this.descricao = descricao;
		this.idade = idade;
		this.jugs = jugs;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public Endereco getEndereco() {
		return endereco;
	}

	public void setEndereco(Endereco endereco) {
		this.endereco = endereco;
	}

	public ObjectId get_id() {
		return _id;
	}

	public int getIdade() {
		return idade;
	}

	public void setIdade(int idade) {
		this.idade = idade;
	}

	public String getJugs() {
		return jugs;
	}

	public void setJugs(String jugs) {
		this.jugs = jugs;
	}
}

A anotação @FormParam, são utilizados para pegar os valores do form do html.

package br.com.danieldias.model;

/**
 * @author daniel
 * github:Daniel-Dos
 * daniel.dias.analistati@gmail.com
 * twitter:@danieldiasjava
 */
public class Endereco {

	private String estado;

	public String getEstado() {
		return estado;
	}

	public void setEstado(String estado) {
		this.estado = estado;
	}

	public Endereco() {
	}

	public Endereco(String estado) {
		super();
		this.estado = estado;
	}
}

Criando o Repositorio

Agora criaremos uma Inteface chamada MongoDAO ,uma classe chamada PessoaDAO e uma classe que ira criar a fabrica de conexão chamada MongoDBFactory no package br.com.danieldias.persistencia, com os seguintes conteúdos:

package br.com.danieldias.persistencia;

import com.mongodb.MongoClient;

/**
 * @author daniel
 * github:Daniel-Dos
 * daniel.dias.analistati@gmail.com
 * twitter:@danieldiasjava
 */
public class MongoDBFactory {

	public static MongoClient createConnection() {
		MongoClient conexao = null;
		if(conexao == null) {
			conexao = new MongoClient();
		}
		return conexao;
	}
}

A classe PessoaDAO é onde fica todas as operações de CRUD para o MongoDB, nada muito fora do comum, tudo muito simples e fácil compreensão. Repare que estamos usando a classe Constantes aqui no lugar de String para facilitar o entendimento e deixar o código mas limpo.

package br.com.danieldias.persistencia;

import static com.mongodb.client.model.Filters.eq;

import java.util.ArrayList;
import java.util.List;

import org.bson.Document;
import org.bson.types.ObjectId;

import com.mongodb.MongoClient;
import com.mongodb.MongoCursorNotFoundException;
import com.mongodb.MongoException;
import com.mongodb.MongoQueryException;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;

import br.com.danieldias.commons.Constantes;
import br.com.danieldias.model.Pessoa;

/**
 * @author daniel
 * github:Daniel-Dos
 * daniel.dias.analistati@gmail.com
 * twitter:@danieldiasjava
 */
public class PessoaDao implements MongoDAO<Pessoa> {

	MongoClient conexao;
	MongoCollection<Document> collectionPessoas;

	public PessoaDao() {
		conexao = MongoDBFactory.createConnection();
		collectionPessoas =
				conexao.getDatabase(Constantes.BANCO_NOME)
				.getCollection(Constantes.COLLECTION_NOME);
	}

	@Override
	public void inserir(Pessoa entidade) throws MongoException {

		List<Document> jugs = new ArrayList<>();
		jugs.add(new Document(Constantes.NOME,entidade.getJugs())
				.append(Constantes.DESCRICAO, entidade.getDescricao()));

		collectionPessoas.insertOne(new Document(Constantes.NOME,entidade.getNome())
				 .append(Constantes.ENDERECO,
							new Document(Constantes.ESTADO,entidade.getEndereco().getEstado())
							)
				 .append(Constantes.IDADE,entidade.getIdade())
				 .append(Constantes.JUGS, jugs)
				 );
	}

	@Override
	public void alterar(Pessoa entidade) throws MongoException {

		collectionPessoas.updateOne(porId(entidade.get_id()),
				new Document("$set",
						new Document(Constantes.IDADE,entidade.getIdade())
						.append(Constantes.NOME, entidade.getNome())
						.append(Constantes.ENDERECO,
								new Document(Constantes.ESTADO,entidade.getEndereco().getEstado()))
						)
				);
	}

	@Override
	public void deletar(ObjectId _id) throws MongoQueryException {
		collectionPessoas.findOneAndDelete(porId(_id));
	}

	@Override
	public MongoCursor<Document> listarTodos() throws MongoCursorNotFoundException, MongoQueryException {
		return collectionPessoas.find().iterator();
	}

	@Override
	public Document porId(ObjectId _id) throws MongoQueryException {
		return collectionPessoas.find(eq(Constantes.ID,_id)).first();
	}
}

Agora nossa interface generica:

package br.com.danieldias.persistencia;

import org.bson.Document;
import org.bson.types.ObjectId;

import com.mongodb.MongoCursorNotFoundException;
import com.mongodb.MongoException;
import com.mongodb.MongoQueryException;
import com.mongodb.client.MongoCursor;

/**
 * @author daniel
 * github:Daniel-Dos
 * daniel.dias.analistati@gmail.com
 * twitter:@danieldiasjava
 */
public interface MongoDAO<T> {

	void inserir(T entidade) throws MongoException;
	void alterar(T entidade) throws MongoException;
	void deletar(ObjectId _id) throws MongoQueryException;
	MongoCursor<Document> listarTodos() throws MongoCursorNotFoundException,MongoQueryException;
	Document porId(ObjectId _id) throws MongoQueryException;
}

Criando os Controles

Entramos na parte principal, aqui veremos com a api funciona.

Crie uma nova classe chamada PessoaController no package br.com.danieldias.controller, com o seguinte conteúdo :

package br.com.danieldias.controller;

import javax.inject.Inject;
import javax.mvc.Models;
import javax.mvc.Viewable;
import javax.mvc.annotation.Controller;
import javax.mvc.annotation.View;
import javax.ws.rs.BeanParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;

import org.bson.types.ObjectId;

import br.com.danieldias.model.Pessoa;
import br.com.danieldias.persistencia.MongoDAO;

/**
 * @author daniel
 * github:Daniel-Dos
 * daniel.dias.analistati@gmail.com
 * twitter:@danieldiasjava
 */
@Controller
@Path("mvc")
public class PessoaController {

	@Inject
	Models models;

	@Inject
	MongoDAO<Pessoa> pessoaDao;

	@GET
	@Path("novo")
	public Viewable novo() {
		return new Viewable("inserir.jsp");
	}

	@GET
	@Path("mostrar")
	@View("mostrar.jsp")
	public void listar() {
	  this.models.put("listar", pessoaDao.listarTodos());
	}

	@POST
	@Path("add")
	public String adicionar(@BeanParam Pessoa pessoa) {
		pessoaDao.inserir(pessoa);

		return "redirect:mvc/mostrar";
	}

	@POST
	@Path("update")
	public String atualizar(@BeanParam Pessoa pessoa) {
		pessoaDao.alterar(pessoa);
		return "redirect:mvc/mostrar";
	}

	@GET
	@Path("atualizar/{_id}")
	public Viewable update(@PathParam("_id") ObjectId _id) {
		this.models.put("update",pessoaDao.porId(_id));
		return new Viewable("alterar.jsp",models);
	}

	@GET
	@Path("remover/{_id}")
	public String deletar(@PathParam("_id") ObjectId _id) {
		pessoaDao.deletar(_id);
		return "redirect:mvc/mostrar";
	}
}

O código é semelhante ao que usamos no Spring. Então nessa parte fica bem tranquila de aprender quando a API for lançada oficialmente, é até la vai haver muitas mudanças e melhoramentos.

O @Controller, quando aplicada a uma classe, todos os métodos nele são considerados como controladores. Ao usar a anotação @Controller em um subconjunto de métodos define uma classe hibrida em que certos métodos são controladores e outros são métodos tradicionais do JAX-RS.

O @Path é o endereço que iremos acessar determinada ação para o controlador e acessar outros métodos por outras endereços também, isso é semelhante ao @RequestMapping() do spring.

A class Viewable encapsula informações sobre uma visualização, bem como, opcionalmente, informações sobre como ele deve ser processado. Mais precisamente, uma instância Viewable pode incluir referências a Modelos e Objetos ViewEngine. Comparada ao Spring ela seria como ModelAndView.

Models é a interface que define um mapa entre nomes e objetos. O suporte para a interface Models é obrigatória para todos os view engines, porém podemos usar OPCIONALMENTE o @Named  do CDI que é fortemente recomendado para aproveitar a integração CDI e EL existente na plataforma.

Os métodos do controlador que retornam um tipo não-vazio(void) também podem ser decorados com @View como uma forma de especificar um padrão para o controlador. A visualização padrão deve ser usada somente quando tal controlador não vazio retorna um valor nulo.

A anotação @BeanParam é algo novo adicionado na especificação JAX-RS 2.0. Ele permite que você injete uma classe específica de aplicativo cujos métodos de propriedade ou campos são anotados com qualquer um dos parâmetros de injeção, como foi utilizada o @FormParam.

@PathParam permite que você injete o valor de parâmetros de caminho URI nomeados que foram definidos em expressões @Path.

Criando as Views

Agora daremos inicio a criação de 4 páginas para nossa aplicação que são : alterar.jsp, inserir.jsp ,mostrar.jsp  que devem ser criada na pasta views que fica dentro de WEB-INF, já a index.jsp deve ser criada em na pasta  webapp.

Iniciaremos pela a página mostrar.jsp, onde a mesma terá uma tabela onde os dados serão apresentados, 3 links um para chamar a paǵina alterar.jsp passando um parâmetro que é seu id e um que irá chamar no controle o deletar com parâmetro id e um para estarmos adicionando os dados no formulario inserir.jsp :

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!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>Mostrar</title>
</head>
<body>

<h1 align="center">Listagem dos Dados</h1>

<a href="novo">Adicionar</a>

		<table align="center" border="4">
		<tr bgcolor="gray">
		    <th>ID</th>
			<th>Nome</th>
			<th>Idade</th>
			<th>Estado</th>
			<th>JUGS</th>
			<th>Descrição</th>
			<th>Editar</th>
			<th>Deletar</th>
		</tr>
		<c:forEach items="${listar}" var="pessoas">
			<tr>
				<td>${pessoas._id}</td>
				<td>${pessoas.nome}</td>
				<td>${pessoas.idade}</td>
				<td>${pessoas.endereco.estado}</td>
				<td>${pessoas.jugs.get(0).nome}</td>
				<td>
				<textarea rows="10" cols="60" name="descricao" disabled="disabled"> ${pessoas.jugs.get(0).descricao} </textarea>
				</td>
				<td><a href="atualizar/${pessoas._id }">Alterar</a></td>
				<td><a href="remover/${pessoas._id}">Excluir</a></td>
			</tr>
		</c:forEach>
	</table>

     
       
</body>
</html>

Algo importante nesta tela. Aqui os atributos passado devem SER o mesmo que estão no mongoDB, ou seja as colunas tem que ter os mesmo nome. A mesma coisa nesse techo : ${pessoas.jugs.get(0).nome}, aqui estou retornado o primeiro posição no array, se quisermos chamar outra posição fazemos assim : ${pessoas.jugs.get(1).lideres}.
A proxima tela é um formulario bem simples com o seguinte conteudo :

<%@ page language="java" contentType="text/html; charset=UTF-8"     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>Inserir</title>
</head>
<body>
<div align="center">
<form action="add" method="post">
<fieldset style="width: 400px">
<legend>Dados</legend>

	 Nome: <input type="text" name="nome" />

    Idade: <input type="number" name="idade"/>

   Estado: <input type="text" name="endereco"/>

   JUGS:<input type="radio" name="jugs" value="SouJava"/>SouJava
   <input type="radio" name="jugs" value="RioJug"/>RioJug
   <input type="radio" name="jugs" value="SouJava Campinas"/>SouJava Campinas

   <textarea rows="10" cols="30" name="descricao">Descrição</textarea>

   <input type="submit" value="Cadastrar Dados."/></fieldset>
</form></div>
</body>
</html>

e última tela que contem um formulário já preenchido com os valores do banco que podem ser alterados :

<%@page contentType="text/html" language="java" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Atualizar Dados</title>
</head>
<body>
<div align="center">
<form action="../update" method="post">
<fieldset style="width: 400px">
<legend>Alteração de Dados</legend>

		<input type="text" name="_id" value="${update._id }" hidden="true">

      Nome:<input type="text" name="nome" value="${update.nome }">

      Idade: <input type="number" name="idade" value="${update.idade }"/>

      Cidade<input type="text" name="endereco"  value="${update.endereco.estado}">

      <textarea rows="10" cols="30" name="descricao" disabled="disabled">${update.jugs.get(0).descricao}</textarea>

      <input type="submit" value="Atualizar"></fieldset>
</form></div>
</body>
</html>

agora nossa pagina index.jsp contendo a url para chamar a tela mostrar.jsp e iniciar a aplicação.

<%@ page language="java" contentType="text/html; charset=UTF-8"     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>Index MVC</title>
</head>
<body>
<h1 align="center">Demo JSR 371 - MVC 1.0</h1>
<div align="center">
<ul type="none">
	<li ><a href="app/mvc/mostrar">Listar Dados</a></li>
</ul>
</div>
</body>
</html>

por fim iniciar a aplicação devemos criar uma classe que extenda a javax.ws.rs.core.Application e anota-la com @ApplicationPath, essa classe deve ser criada no package br.com.danieldias.application com o seguinte conteúdo :

package br.com.danieldias.application;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

/**
 * @author daniel
 * github:Daniel-Dos
 * daniel.dias.analistati@gmail.com
 * twitter:@danieldiasjava
 */
@ApplicationPath("app")
public class MVCApplication extends Application {
}

Rodando a Aplicação

Com tudo pronto, podemos testar a nossa aplicação:
Primeiramente inicie o MongoDB através do prompt/terminal com o seguinte comando : mongod, como na imagem:

mongod

Depois rode a aplicação no glassfish , com o botão direito do mouse clique no seu projeto e vá em Run As -> Run on Server, ao inicia a aplicação a página principal será carregada com abaixo :

indexmvc

Clique no link  para ser levado a pagina que lista todos os dados, como na imagem :

telamvc

Clique no link Adicionar, irá ser levado para a tela de formulário:

telamvc2

Ao clicar em Cadastrar Dados, voltará para a tela de listagem dos dados :

listagem

Agora clicando em Excluir irá deletar a informação através do ID que foi passado por parâmetro. Em Alterar será levado a tela de alteração de dados e retornara para tela de listagem :

alterar

Bem isso é tudo, aqui aprendemos a como fazer uma aplicação utilizado a api MVC1.0 do JEE 8 com MongoDB . O projeto pode ser baixado no meu GitHub.

Outros exemplos da API pode ser encontrados aqui : https://github.com/spericas/ozark/tree/master/test
Para saber mais sobre a API visite os seguintes sites :

mvc-spec

Ozark- RIOzark- RI

mvc-1-0-jsr-para-um-framework-mvc-action-based-na-java-ee-8

primeiros-passos-do-mvc-1-0

REFERÊNCIAS

https://dennis-xlc.gitbooks.io/restful-java-with-jax-rs-2-0-2rd-edition/content/en/index.html

https://jcp.org/en/jsr/detail?id=371

http://download.oracle.com/otn-pub/jcp/mvc-1-edr2-spec/JSR_371-EDR-Spec-MVC-1_0-10_2_15.pdf

Aplicação Spring MVC com MongoDB

Neste artigo criaremos um aplicação simples utilizando Spring MVC juntamente com MongoDB.

Boa Leitura.

capa

Antes de começarmos a criar nosso projeto, primeiramente tem que conhecer um pouco sobre  o banco de dados mongodb e Mongo Shell. Sua instalação pode ser vista aqui Obtendo e Configurando o MongoDB em seu Ambiente.

Spring MVC  é um framework  Action Based que tem ganhado bastante espaço ultimamente no universo Java para criação de projeto Web, antes dele era Struts 1 que também é um framework Action Based.

O projeto vai ser bem simples, um crud utilizando mongodb com um relacionamento entre dois documentos.

Criando o Projeto

Com o Eclipse aberto, vá File -> New – > Maven Project irá abrir a seguinte Janela :

maven

clique em Next para ir para a seguinte tela :

maven2

clique em Next, na próxima deixe preenchida da seguinte forma  e clique em Finish:

blog2

com o projeto criado,vá em src/main/webapp, nela apague a pasta WEB-INF. Depois clique com o botão direito do mouse e vá em Properties, navegue até a opção Targeted Runtimes, marque a opção, que no caso vamos utilizar o Tomcat, depois clique em Uninstall Facets… :

target-maven

facets

ao chegar nesta tela desmaque Dynamic Web Module , altere Java 1.5 para 1.8 e clique em Finish. Abra novamente a mesma tela e maque Dynamic Web Module e mude de 2.3 para 3.1 e clique em Next para configura a proxima tela e a configure como abaixo :

web

Clique em Finish e depois em OK.

Agora iremos configurar nosso pom.xml, com a seguinte configurações :

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>br.com.danieldias</groupId>
	<artifactId>SpringMongo</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>SpringMongo Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<dependencies>
		<!-- Mongo Driver -->
		<dependency>
			<groupId>org.mongodb</groupId>
			<artifactId>mongodb-driver</artifactId>
			<version>3.2.2</version>
		</dependency>

		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>4.3.0.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>4.3.0.RELEASE</version>
		</dependency>

		<!-- JSTL -->
		<dependency>
			<groupId>jstl</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>

		<!-- Servlet -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>SpringMongo</finalName>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.5.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>
</project>

Na pasta WEB-INF , configure o web.xml na seguinte forma :

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation=" http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
  <display-name>SpringMongo</display-name>

  <servlet>
    <servlet-name>springDispatcherServlet</servlet-name>
    <servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/spring-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
<servlet-mapping>
    <servlet-name>springDispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

Ainda dentro de WEB-INF crie um xml com o nome spring-context.xml, com o seguinte conteúdo e também crie uma pasta chamada views:

<?xml version="1.0" encoding="UTF-8"?>
<beans  xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">

<!-- scaneia todos os pacotes a procura de componentes do Spring-->
  <context:component-scan base-package="br.com.danieldias"/> 

      <context:annotation-config />
	<mvc:annotation-driven />

<!-- configura css,js,etc -->
<mvc:resources location="/recursos/" mapping="/recursos/**"/>

	<!-- Configurando a localização das Views. -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
			<property name="prefix" value="/WEB-INF/views/"/>
			<property name="suffix" value=".jsp"/>
	</bean>

</beans>

Agora na pasta webapp crie uma pasta chamada recursos com as seguinte subpastas : css, js e imagens, dentro de cada uma delas  seguinte arquivos :

  • jquery-ui-1.9.2.custom.min.css
  • calendar.gif
  • datepicker-pt-BR.js
  • jquery-3.1.0.min.js
  • jquery-ui-1.9.2.custom.min.js

Depois clique em cima do projeto e de “Alt +F5” para fazer update do maven :

f5

Clique em OK e finalizamos a parte de criação projeto, podemos da inicio a codificação de nossas classes .

Criando a Constantes.java

Está classe é bem simples, ela irá somente conter valores constantes, que não serão modificadas. Isso para evitar ter muitas hardCode espalhado por todo o código, assim esse classe irá centralizar tudo de maneira organizada.

Crie uma classe chamada Constantes no package br.com.danieldias.commons, com o seguinte conteúdo :

package br.com.danieldias.commons;

/**
 * @author daniel
 * github:Daniel-Dos
 * daniel.dias.analistati@gmail.com
 * twitter:@danieldiasjava
 */
public class Constantes {

	/*Nome o Banco e da Collection*/
	public static final String BANCO_NOME = "danieldiasjava";
	public static final String COLLECTION_NOME = "pessoas";

	/*Nomes das Colunas para o MongoDB*/
	public static final String NOME = "nome";
	public static final String IDADE = "idade";
	public static final String PROFISSAO = "profissao";
	public static final String ENDERECO = "endereco";
	public static final String CIDADE = "cidade";
	public static final String BAIRRO = "bairro";
	public static final String ESTADO = "estado";
	public static final String NASCIMENTO = "nascimento";
	public static final String JUGS = "jugs";
}

Criando as Entidades

Crie as classes Pessoa.java e Endereco.java no package br.com.danieldias.model , com o seguinte conteúdo :

package br.com.danieldias.model;

import java.util.Calendar;

import org.springframework.format.annotation.DateTimeFormat;

/**
 * @author daniel
 * github:Daniel-Dos
 * daniel.dias.analistati@gmail.com
 * twitter:@danieldiasjava
 */
public class Pessoa {

	private String nome;
	private String profissao;
	private String jugs;
	private int idade;
	private Endereco endereco;

	@DateTimeFormat(pattern="dd/MM/yyyy")
	private Calendar dataNascimento;

	public Pessoa() {
		this("","","",0,null,null);
	}

	public Pessoa(String nome, String profissao,
		      String jugs, int idade,
		      Endereco endereco,Calendar dataNascimento) {
		this.nome = nome;
		this.profissao = profissao;
		this.jugs = jugs;
		this.idade = idade;
		this.endereco = endereco;
		this.dataNascimento = dataNascimento;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getProfissao() {
		return profissao;
	}

	public void setProfissao(String profissao) {
		this.profissao = profissao;
	}

	public String getJugs() {
		return jugs;
	}

	public void setJugs(String jugs) {
		this.jugs = jugs;
	}

	public int getIdade() {
		return idade;
	}

	public void setIdade(int idade) {
		this.idade = idade;
	}

	public Endereco getEndereco() {
		return endereco;
	}

	public void setEndereco(Endereco endereco) {
		this.endereco = endereco;
	}

	public Calendar getDataNascimento() {
		return dataNascimento;
	}

	public void setDataNascimento(Calendar dataNascimento) {
		this.dataNascimento = dataNascimento;
	}
}

A classe pessoa bem simples, apenas com uma anotação na dataNascimento para o Spring lidar com esse tipo.

package br.com.danieldias.model;

/**
 * @author daniel
 * github:Daniel-Dos
 * daniel.dias.analistati@gmail.com
 * twitter:@danieldiasjava
 */
public class Endereco {

	private String cidade;
	private String bairro;
	private String estado;

	public Endereco() {
		this("","","");
	}

	public Endereco(String cidade, String bairro, String estado) {
		this.setCidade(cidade);
		this.setBairro(bairro);
		this.setEstado(estado);
	}

	public String getCidade() {
		return cidade;
	}

	public void setCidade(String cidade) {
		this.cidade = cidade;
	}

	public String getBairro() {
		return bairro;
	}

	public void setBairro(String bairro) {
		this.bairro = bairro;
	}

	public String getEstado() {
		return estado;
	}

	public void setEstado(String estado) {
		this.estado = estado;
	}
}

Criando o Repositorio

Agora criaremos uma Inteface chamada MongoDAO e uma classe chamada PessoaDAO no package br.com.danieldias.persistencia, com os seguintes conteúdos:

package br.com.danieldias.persistencia;

import org.bson.Document;

import com.mongodb.client.MongoCursor;

import br.com.danieldias.model.Pessoa;

/**
 * @author daniel
 * github:Daniel-Dos
 * daniel.dias.analistati@gmail.com
 * twitter:@danieldiasjava
 */
public interface MongoDAO {

	void inserir(Pessoa pessoa);
	void atualizar(Pessoa pessoa);
	void excluir(Object _id);
	Document porId(Object _id);
	MongoCursor<Document>mostraTodos();
}

A classe PessoaDAO é onde fica todas as operações de CRUD para o MongoDB, nada muito fora do comum, tudo muito simples e fácil compreensão. Repare que estamos usando a classe Constantes aqui  no lugar de String para facilitar o entendimento e deixar o código mas limpo.

package br.com.danieldias.persistencia;

import static com.mongodb.client.model.Filters.eq;
import java.util.ArrayList;
import java.util.List;

import org.bson.Document;
import org.springframework.stereotype.Repository;

import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;

import br.com.danieldias.commons.Constantes;
import br.com.danieldias.model.Pessoa;

/**
 * @author daniel
 * github:Daniel-Dos
 * daniel.dias.analistati@gmail.com
 * twitter:@danieldiasjava
 */
@Repository
public class PessoaDAO implements MongoDAO {

	MongoClient conexao;
	MongoDatabase dataBase;
	MongoCollection<Document> collectionPessoas;

	public PessoaDAO() {
		conexao = new MongoClient();
		dataBase = conexao.getDatabase(Constantes.BANCO_NOME);
		collectionPessoas = dataBase.getCollection(Constantes.COLLECTION_NOME);
	}

	@Override
	public void inserir(Pessoa pessoa) {

		List<Document> jugs = new ArrayList<>();
		jugs.add(new Document(Constantes.NOME,pessoa.getJugs()));

		collectionPessoas.insertOne(
				new Document(Constantes.NOME,pessoa.getNome())
				.append(Constantes.IDADE, pessoa.getIdade())
				.append(Constantes.PROFISSAO, pessoa.getProfissao())
				.append(Constantes.ENDERECO,
						new Document(Constantes.CIDADE,pessoa.getEndereco().getCidade())
						.append(Constantes.BAIRRO, pessoa.getEndereco().getBairro())
						.append(Constantes.ESTADO, pessoa.getEndereco().getEstado())
						)
				.append(Constantes.NASCIMENTO, pessoa.getDataNascimento().getTime())
				.append(Constantes.JUGS,jugs)
				);
	}

	@Override
	public void atualizar(Pessoa pessoa) {

		collectionPessoas.updateOne(eq(Constantes.NOME,pessoa.getNome()),
				new Document("$set",
						new Document(Constantes.IDADE,pessoa.getIdade())
						.append(Constantes.PROFISSAO, pessoa.getProfissao())
						.append(Constantes.ENDERECO,
								new Document(Constantes.CIDADE,pessoa.getEndereco().getCidade())
								.append(Constantes.BAIRRO, pessoa.getEndereco().getBairro())
								.append(Constantes.ESTADO, pessoa.getEndereco().getEstado())
								)
						)
				);
	}

	@Override
	public void excluir(Object _id) {

		collectionPessoas.deleteOne(porId(_id));
	}

	@Override
	public Document porId(Object _id) {

		return collectionPessoas.find(eq("_id",_id)).first();
	}

	@Override
	public MongoCursor<Document> mostraTodos() {

		return collectionPessoas.find().iterator();
	}
}

Criando os Controles

O primeiro controle que iremos criar ,será o que chama a pagina principal listando todos os dados do banco quando iniciar a aplicação.

Crie uma nova classe chamada IndexController no package br.com.danieldias.controller, com o seguinte conteúdo :

package br.com.danieldias.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author daniel
 * github:Daniel-Dos
 * daniel.dias.analistati@gmail.com
 * twitter:@danieldiasjava
 */
@Controller
@RequestMapping("*")
public class IndexController {

	@RequestMapping("*")
	public String index() {
		return "redirect:/pessoas/listaPessoa";
	}
}

Ainda no mesmo package cria a classe PessoasControler com o seguinte conteúdo :

package br.com.danieldias.controller;

import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import br.com.danieldias.model.Pessoa;
import br.com.danieldias.persistencia.MongoDAO;

/**
 * @author daniel
 * github:Daniel-Dos
 * daniel.dias.analistati@gmail.com
 * twitter:@danieldiasjava
 */
@Controller
@RequestMapping("/pessoas")
public class PessoasControler {

	@Autowired
	MongoDAO dao;

	@GetMapping("/inserirPessoa.html")
	public ModelAndView cadastrar() {
		return new ModelAndView("inserirPessoa");
	}

	@GetMapping("/alterarPessoa.html/{_id}")
	public ModelAndView alterar(@PathVariable("_id") ObjectId _id) {
		return new ModelAndView("alterarPessoa","atualizar",dao.porId(_id));
	}

	@PostMapping("inserirPessoa")
	public String adicionar(Pessoa pessoa) {
		dao.inserir(pessoa);
		return "redirect:/pessoas/listaPessoa";
	}

	@GetMapping("listaPessoa")
	public String listar(Model model) {
		model.addAttribute("listas", dao.mostraTodos());
		return "lista";
	}

	@PostMapping("alterar")
	public String update(Pessoa pessoa) {
		dao.atualizar(pessoa);
		return "redirect:/pessoas/listaPessoa";
	}

	@GetMapping("remover/{_id}")
	public String deletar(@PathVariable("_id") ObjectId _id) {
		dao.excluir(_id);
		return "redirect:/pessoas/listaPessoa";
	}
}

Está classe também tem um conteúdo bem simples, a única diferença são as novas anotações para Mapping que a partir do Spring 4.3.0 , podemos está utilizando essas anotações : @GetMapping, @PostMapping, que são a mesma coisa quando fazemos desta maneira : @RequestMapping(value = “alterar”, method = “RequestMethod.POST”)

Criando as Views

Agora daremos inicio a criação de 3 páginas para nossa aplicação que são : alterarPessoa.jsp, inserirPessoa.jsp e lista.jsp, que devem ser criada na pasta views que fica dentro de WEB-INF .

Iniciaremos pela a página lista.jsp, onde a mesma terá uma tabela onde os dados serão apresentados, 3 links um para chamar a paǵina alterarPessoa.jsp passando um parâmetro que é seu id e um que irá chamar no controle o deletar com parâmetro id e um para estarmos adicionando os dados no formulario inserirPessoa.jsp

A página fica da seguinte forma :

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ 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=UTF-8">
<title>Lista de Pessoas</title>
</head>
<body>
		<h1 align="center">Listagem dos Dados</h1>
<a href="inserirPessoa.html">Adicionar</a>
		<table align="center" border="4">
		<tr bgcolor="gray">
		    <th>ID</th>
			<th>Nome</th>
			<th>Idade</th>
			<th>Profissão</th>
			<th>Cidade</th>
			<th>Bairro</th>
			<th>Estado</th>
			<th>Jugs</th>
			<th>Data</th>
			<th>Editar</th>
			<th>Deletar</th>
		</tr>
		<c:forEach items="${listas}" var="pessoas">
			<tr>
				<td>${pessoas._id}</td>
				<td>${pessoas.nome}</td>
				<td>${pessoas.idade}</td>
				<td>${pessoas.profissao}</td>
				<td>${pessoas.endereco.cidade}</td>
				<td>${pessoas.endereco.bairro}</td>
				<td>${pessoas.endereco.estado}</td>
				<td>${pessoas.jugs.get(0).nome}</td>
				<td>
				<fmt:formatDate value="${pessoas.nascimento}" pattern="dd/MM/yyyy"/>
				</td>
				<td><a href="alterarPessoa.html/${pessoas._id }">Alterar</a></td>
				<td><a href="remover/${pessoas._id}">Excluir</a></td>
			</tr>
		</c:forEach>
	</table>
</body>
</html>

Algo importante nesta tela. Aqui os atributos passado devem SER o mesmo que estão no mongoDB, ou seja as colunas tem que ter os mesmo nome. A mesma coisa nesse techo : ${pessoas.jugs.get(0).nome}, aqui estou retornado o primeiro posição no array, se quisermos chamar outra posição fazemos assim : ${pessoas.jugs.get(1).lideres}.

A proxima tela é um formulario bem simples com o seguinte conteudo :

<%@ page language="java" contentType="text/html; charset=UTF-8"     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>Inserir Pessoas</title>
	<link rel="stylesheet" href="../recursos/css/jquery-ui-1.9.2.custom.min.css">
<script src="../recursos/js/jquery-3.1.0.min.js"></script>
<script src="../recursos/js/jquery-ui-1.9.2.custom.min.js"></script>
<script src="../recursos/js/datepicker-pt-BR.js"></script>
<script type="text/javascript">
		$(function(){
		  $("#date").datepicker({
		      showOn:"button",
			  buttonImage:"../recursos/imagem/calendar.gif",
			  buttonImageOnly:true
		   });
		});
		</script>

</head>
<body>
<form  action="inserirPessoa" method="post">
<fieldset>
<legend>Dados</legend>

   Nome: <input type="text" name="nome" />

   Idade: <input type="number" name="idade"/>

   Profissão: <input type="text" name="profissao"/>

   Cidade: <input type="text" name="endereco.cidade"/>

   Bairro: <input type="text" name="endereco.bairro"/>

   Estado: <input type="text" name="endereco.estado"/>

   Data de Nascimento: <input id="date" type="text" name="dataNascimento" placeholder="dd/mm/yyyy"/>

   JUGS:
   <input type="checkbox" name="jugs" value="SouJava"/>SouJava
   <input type="checkbox" name="jugs" value="RioJug"/>RioJug
   <input type="checkbox" name="jugs" value="SouJava Campinas"/>SouJava Campinas

   <input type="submit" value="Cadastrar Dados."/></fieldset>
</form>

</body>
</html>

e última tela que contem um formulário já preenchido com os valores do banco que podem ser alterados :

<%@ page language="java" contentType="text/html; charset=UTF-8"     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>Alterar Pessoas</title>
</head>
<body>
<form  action="../alterar" method="post">
<fieldset>
<legend>Alteração de Dados</legend>

	Nome: <input type="text" name="nome" value="${atualizar.nome}" disabled="disabled"/>

    Idade: <input type="number" name="idade" value="${atualizar.idade}"/>

    Profissão: <input type="text" name="profissao" value="${atualizar.profissao}"/>

    Cidade: <input type="text" name="endereco.cidade" value="${atualizar.endereco.cidade}"/>

    Bairro: <input type="text" name="endereco.bairro" value="${atualizar.endereco.bairro}"/>

    Estado: <input type="text" name="endereco.estado" value="${atualizar.endereco.estado}"/>

              <input type="submit" value="Alterar Dados."/></fieldset>
</form>

</body>
</html>

Rodando a Aplicação

Com tudo pronto, podemos testar a nossa aplicação:

Primeiramente inicie o MongoDB  através do prompt/terminal com o seguinte comando : mongod, como na imagem

mongod

Depois rode a aplicação no tomcat , com o botão direito do mouse clique no seu projeto e vá em Run As -> Run on Server, ao inicia a aplicação a página principal será carregada com abaixo :

lista

Ao clicar em Adicionar irá para a tela de cadastro :

cadatrar

Ao clicar em adicionar, a pagina irá redirecionar para a tela principal novamente com os dados carregados :

retorno

Ao clicar no link Alterar, vai carregar a pagina de alteração de dados e se clicar em Excluir vai apagar o dado e vai voltar para a pagina principal :

alterar

RoboMongo

Com os nossos dados Gravados, podemos ver como fica a sua estrutura no banco, ao invés de utilizar o mongo Shell para visualizar os dados , irei usar uma ferramente de administraçao para está lidando com varias operações referente ao MongoDB, essa ferramente se chama RoboMongo , instalação facil basta descompactar e executar .

Ao executar o RoboMongo irá aparecer a seguinte tela :

robomongo

clique em Create , de um nome para a conexao e clique em OK :

teste

depois de salvo, clique em Connect, que irar leva-lo a seguinte pagina,basta clicar na collection pessoas e ira carregar os dados armazenados :

mostar

Bem isso é tudo, aqui aprendemos a como fazer uma aplicação Spring MVC com MongoDB e de quebra conhecemos uma nova ferramenta para o mesmo. O projeto pode ser baixado no meu GitHub.

REFERÊNCIAS

 http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/

PERSISTINDO DADOS COM HIBERNATE OGM

A última parte prática da  minha monografia de especialização em Desenvolvimento Java. Neste capitulo irá aprender a usar o Framework de Persistência Hibernate OGM para bancos NoSQL .

Boa Leitura.

Assim como existe o Hibernate ORM (object-relational mapping), que é utilizado para mapeamentos entre os bancos relacionais, existe também o Hibernate OGM (Object/Grid Mapper) para estar trabalhando com bancos NoSQL.

Segundo Leonard (2013), o Hibernate OGM utiliza módulos do Hibernate ORM tanto quanto possível, a arquitetura OGM essencialmente estende a arquitetura ORM, ligando diferentes componentes dentro e fora. De acordo com ele, o Hibernate ORM converte e persiste dado entre os bancos relacionais e as linguagens de programação orientada a objetos, utilizando um conjunto de interfaces e classes. Este inclui uma camada JDBC para esta ligando as bases de dados e envio de consultas e as interfaces persistentes e carregadores, que são responsáveis pela persistência e entidades de carga e coleções.

Leonard (2013) explica que o Hibernate OGM é destinado a realizar os mesmos objetivos que o ORM, porem usando NoSQL. A diferença entre eles, é que no ORM precisamos da camada JDBC, mas no OGM essa camada não é necessária, em vez disso ela oferece dois novos elementos que são: um provedor de armazenamento de dados e um dialeto de armazenamento de dados.

Marchioni (2015) explica que uma aplicação ira interagir com a JPA ou com a API nativa do Hibernate. Uma vez que ela utiliza os recursos do ORM como explicado anteriormente, onde estão contidos no núcleo do Hibernate. Por sua vez, são delegados do núcleo hibernate a execução de consultas e operações CRUD para o Hibernate OGM.

De acordo Marchioni (2015) o mecanismo de consulta ira conduzir a execução de instruções JP-QL para o armazenamento subjacente. Outras operações de CRUD vai ser executada para ser diretamente armazenada, com a mediação do provedor de armazenamento de dados, que seria o uso do controlador MongoDB para o nosso caso.

A figura 65 descreve a arquitetura do Hibernate OGM, mostrando sua relação com o Hibernate ORM, como foi explicado por Marchioni.

ogm
Figura 65 – Arquitetura Hibernate OGM Fonte: MARCHIONI, 2015. p. 118

CRIANDO UM PROJETO JAVA WEB UTILIZANDO HIBERNATE OGM

Iremos reaproveitar o projeto web criado na sessão anterior, para esta atualizando o mesmo para esta funcionando com o Hibernate OGM.

Primeiramente vamos adicionar a dependência do Hibernate OGM no arquivo pom.xml do projeto anterior. O arquivo deve contém os seguintes trechos:

      <depencendyManagement>
            <dependencies>
                  <dependency>
                         <groupId>org.hibernate.ogm</groupId>
                         <artifactId>hibernate-ogm-bom</artifactId>
                         <version>5.0.0.Final</version>
                         <type>pom</type>
                         <scope>import</scope>
                    </dependency>
              </dependencies>
      </dependencyManagement>

     <dependencies>
           <dependency>
                <groupId>org.hibernate.ogm</groupId>
                <artifactId>hibernate-ogm-mongodb</artifactId>
           </dependency>
    </dependencies>

Figura 66 – Dependência Hibernate OGM Fonte: Autoria Própria

A Figura 66, adicionamos duas dependências para o projeto. A primeira ira ser feita o download de toda a biblioteca para o Hibernate OGM. O segundo irá fazer o download do mongo drive.

MAPEANDO AS COLEÇÕES DE BANCO DE DADOS

Vamos agora adicionar classes Java, para fazer o mapeamento. Aqui utilizaremos a mesma classe da figura 56, mas com elementos para funcionar com framework. A figura 67, adicionamos anotações na classe para que seja reconhecida no hibernate OGM.

Assim como no Hibernate ORM, estas anotações têm o mesmo efeito no Hibernate OGM, onde:

  • @Entity: Uma classe anotada com ela se torna uma classe entidade, ou seja,
    se torna um documento e os seus atributos se tornam os campos do
    documento.
  • @Id: Diz que o atributo é chave primaria da tabela.
@Entity
public class Pessoa {

    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
     private String id;

     private String nome;
     private int idade;
     private String email;
     private String telefone;

     public Pessoa(String id,String nome, int idade, String email, String telefone) {
          this.id = id;
          this.nome = nome;
          this.idade = idade;
          this.email = email;
          this.telefone = telefone;
       }

     public Pessoa() {
       this.("","",0,"","");
   }

    // Getter e Setter foram emitido para abreviar.
 

Figura 67 – Classe entidade Fonte: Autoria Própria

CONFIGURANDO O PERSISTENCE.XML

Para podemos está acessando banco de dados, teremos que configura um arquivo de configuração do JPA chamado persistence.xml a sua configuração é bem semelhante quando se uso o Hibernate ORM.

Esse arquivo deve ser criado na seguinte pasta do projeto src/main/resources/META-INF:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.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_2_0.xsd">

	<persistence-unit name="TCC" transaction-type="RESOURCE_LOCAL">
		<provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>
		<class>br.com.danieldias.tcc.modelo.Pessoa</class>

		<properties>
			<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" />
			<property name="hibernate.ogm.datastore.database" value="TCC" />
			<property name="hibernate.ogm.datastore.host" value="127.0.0.1" />
			<property name="hibernate.ogm.datastore.provider" value="MONGODB" />
			<property name="hibernate.ogm.datastore.port" value="27017" />
			<property name="hibernate.ogm.datastore.create_database" value="true" />
		</properties>
	</persistence-unit>
</persistence>

Figura 68 – persistence.xml Fonte: Autoria Própria

INSERINDO COM HIBERNATE OGM

Modificaremos a classe InserirControle, para esta utilizando o JPA para persistir. O código sofrera poucas mudanças, pois iremos apenas mudar a parte de conexão.

Na Figura 69, trocamos a conexão que foi feita na Figura 57. Como podemos notar, o código diminuiu bastante se comparado com a outra.

@WebServlet("/InserirControler")
public class InserirControle extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // criando uma instancia de Pessoa
        Pessoa pessoa = new Pessoa();

        //Recuperando dados do JSP
        pessoa.setNome(request.getParameter("nome"));
        pessoa.setIdade(Integer.parseInt(request.getParameter("idade")));
        pessoa.setTelefone(request.getParameter("telefone"));
        pessoa.setEmail(request.getParameter("email"));

        // Criando o EntityManager
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("TCC");
        EntityManager em = emf.createEntityManager();

        // Criando a transação
        em.getTransaction.begin();

       // Persistindo Dados
       em.persist(pessoa);

      // Enviando o commit para o banco
      em.getTransaction.commit();
      em.close(); // Fechando a conexão
    }
}

Figura 69 – InserirControle Fonte: Autoria Própria.

LISTANDO COM HIBERNATE OGM

Modificaremos a classe ConsultarTodosControler, para trazer os dados a partir do JPA. A figura 70, demonstra como podemos trazer todos os dados da nossa coleção utilizando o JP-QL.

@WebServlet("/ConsultarTodosControler")
public class ConsultarTodosControler extends HttpServlet {
      private static final long serialVersionUID = 1L;

      protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        RequestDispacher visao = null;

        // Criando o EntityManager
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("TCC");
        EntityManager em = emf.createEntityManager();

       // Criando a transação
       em.getTransaction().begin();

      // Criando uma lista de pessoa / JP-QL
      List<Pessoa> pessoas = em.createQuery("FROM Pessoa",Pessoa.class).getResultList();
      em.getTransaction().commit();
      em.close();

     // Configurando um atributo para JSP listar os dados
     request.setAttribute("listas",pessoas);

    // Retorna para a pagina listar.jsp
    visao = request.getRequestDispacher("listar.jsp");
    visao.forward(request,response);
  }
}

Figura 70 – ConsultarTodosControle Fonte: Autoria Própria.

ATUALIZANDO COM HIBERNATE OGM

A classe AlterarControler, irá atualizar 3 campos da collection a partir de uma consulta pelo nome passando o parâmetro utilizando JP-QL, como demonstrada na figura 71.

@WebServlet("/AlterarControler")
public class AlterarControler extends HttpServlet {
     private static final long serialVersionUID = 1L;

     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

      Pessoa pessoa = new Pessoa();

     // Recuperando dados do JSP
     pessoa.setNome(request.getParameter("nome"));
     pessoa.setIdade(Integer.parseInt(request.getParameter("idade")));
     pessoa.setTelefone(request.getParameter("telefone"));
     pessoa.setEmail(request.getParameter("email"));

      // Criando a EntityManager
      EntityManagerFactory emf = Persistence.createEntityManagerFactroy("TCC");
      EntityManager em = emf.createEntityManager();

     // Criando a transação
     em.getTransaction().begin();

     //Criando uma consulta
     Query query = em.createQuery("FROM Pessoa where nome=:nome",Pessoa.class);
     query.setParameter("nome",pessoa.getNome());

     Pessoa id (Pessoa) query.getSingleResult();
     pessoa.setId(id.getId());
     pessoa.setNome(id.getNome());

     em.merge(pessoa);
     em.getTransaction().commit();
     em.close();
    }
}

Figura 71 – AlterarControle Fonte: Autoria Própria.

Após a fazer a consulta, irá trazer um único registro que coincide com o argumento passado. Logo após os métodos setId e setNome, recebe o valor da variável id, para que a mesma são sejam alteradas e que não criem um novo registro no banco.

DELETANDO COM HIBERNATE OGM

Por último, será modificada a classe DeletarControler. Onde utilizamos consulta nativa do MongoDB para estarmos deletando os dados. Onde foi criada uma variável String contendo a operação nativa do MongoDB, que no caso iremos deletar todos os documentos que contém o nome especificado ao passarmos o parâmetro no formato Json do MongoDB, conforme demonstrado na figura 72 .

@WebServlet("/DeletarControle")
public class DeletarControler extends HttpServlet {
     private static final long serialVersionUID = 1L;

     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

      Pessoa pessoa = new Pessoa();

     // Recuperando dados do JSP
     pessoa.setNome(request.getParameter("nome"));

      // Criando a EntityManager
      EntityManagerFactory emf = Persistence.createEntityManagerFactroy("TCC");
      EntityManager em = emf.createEntityManager();

     // Criando a transação
     em.getTransaction().begin();

    // Criando uma consulta nativa
    String query1 = "db.Pessoa.remove({'nome': '" + pessoa.getNome() + "'})";

    Query query = (Query) em.createNativeQuery(query1, Pessoa.class);
    query.executeUpdate();

    em.getTransaction().commit();
    em.close();
    }
}

Figura 72 – DeletarControle Fonte: Autoria Própria.

Contudo, finalizamos este capitulo demonstrando como podemos está construindo sistemas em Java sendo desktop ou web, utilizando MongoDB para armazenamento.

Visto que a implementação para fazer operações no banco via Driver Java é bem simples, já que os métodos contidos no driver são praticamente o mesmo apresentado no Mongo Shell, o que facilita muito no desenvolvimento.

Foi apresentado o Hibernate OGM, um framework para manipulação dos dados no MongoDB, que utilizar módulos do Hibernate ORM.

O framework facilitou ainda mais interação com o MongoDB utilizando JPA ou a API nativa do Hibernate e ainda permite a utilização de operações nativa do MongoDB, que é uma boa escolha se caso sentirmos limitado ao utilizar o Hibernate OGM.

REFERÊNCIAS

Leonard, Anghel. Pro Hibernate and MongoDB. Apress,2013.

Marchioni, Francesco. MongoDB for Java Developers. Birmingham: Packt Publishing Ltd,2015.

JAVA EE E MONGODB

A penúltima parte prática da  minha monografia de especialização em Desenvolvimento Java. Neste capitulo irá aprender a usar MongoDB juntamente com Java EE.

Boa Leitura.

Segundo Marchioni (2015) desenvolver uma aplicação para indústria de TI pode ser um grande desafio para qualquer desenvolvedor, pois a mesma precisa resolver algumas preocupações como segurança, portabilidade e alta disponibilidade. Sem contar que muito dessas aplicações precisa se comunicar com outros sistemas e ser gerado de um ponto central. Com a plataforma Java EE, podemos alavancar todas essas características e muito mais, com foco na preocupação mais importante, que é os seus requisitos de negócios.

Marchioni (2015) explica que o desenvolvimento da plataforma Java EE é feito através do Java Community Process (JCP), ela é uma comunidade encarregada de desenvolver as especificações para toda tecnologia Java. Esta comunidade é composta por especialista da indústria de TI que estabelecem a Java Specification Requests (JSRs), para as tecnologias Java EE. O Java EE é agora mais fácil e mais poderoso a cada novo lançamento. Seu conjunto de APIs disponíveis cresceu rapidamente e se tornando uma grande imagem da tecnologia,
como é mostrada na figura 51:

jee
Figura 51 – API Java EE Fonte: MARCHIONI,2015, p.88

Conforme mostrada na figura 51, o Java EE possuir muitas APIs para se está trabalhando. Utilizaremos alguns componentes do Java EE em nossos exemplos tais como Servlet para estar lidando com as requisições HTTP e a JSP para está interagindo com a Servlet, bem como usar como interface visual para o usuário.

Antes de iniciar o projeto, devemos obter um conteier para que o Java funcione na web. Nos exemplos será utilizado o Apache Tomcat que pode ser obtida em https://tomcat.apache.org/download-80.cgi, basta descompactar em qualquer local do computador e configurar o mesmo eclipse.

CRIANDO UM PROJETO JAVA WEB COM MONGO

Criaremos um projeto semelhante ao anterior utilizando também o maven, porem utilizando recursos do Java EE para construirmos uma aplicação baseada em web. Siga os passos nas figuras 52 a 54 para esta criando o projeto:

maven
Figura 52 – Novo Projeto Fonte: Gerado pelo Eclipse
maven2
Figura 53 – Seleção maven-archetype-webapp Fonte: Gerado pelo Eclipse
maven3
Figura 54 – Configurando o Projeto Fonte: Gerado pelo Eclipse

Após seguir como demonstrada nas figuras 52 a 54, será gerada um projeto no eclipse chamada JavaMongoWeb. Abra o arquivo pom.xml é configure de acordo com a figura 55:

   <dependencies>
           <dependency>
                <groupId>jstl</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
          </dependecy>

          <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
           </dependecy>

           <dependency>
                <groupId>org.mongodb</groupId>
                <artifactId>mongodb-driver</artifactId>
                <version>3.2.2</version>
           </dependecy>
    </dependencies>

 <build>
      <finalName>JavaMongoWeb</finalName>
         <plugins>
              <plugin>
                   <artifactId>maven-compiler-plugin</artifactId>
                        <version>3.1</version>
                       <configuration>
                            <source>1.8</source>
                            <target>1.8</target>
                       </configutation>
                 </plugin>
          </plugins>
     </build>

Figura 55 – Adicionando Dependências – Fonte : Gerado pelo Eclipse

CRIANDO CLASSE MODELO

Nesta sessão será criada uma classe chamada Pessoa e será usado para mapear documentos MongoDB. Elas contêm os mesmos campos correspondentes do documento, conforme a figura 56:

public class Pessoa {

     private String nome;
     private int idade;
     private String email;
     private String telefone;

     public Pessoa(String nome, int idade, String email, String telefone) {
          this.nome = nome;
          this.idade = idade;
          this.email = email;
          this.telefone = telefone;
       }

     public Pessoa() {
       this.("",0,"","");
   }

    // Getter e Setter foram emitido para abreviar.

Figura 56 – Classe Pessoa Fonte: Autoria Própria.

INSERINDO DADOS COM SEVLET E JSP

A figura 56 demonstra uma classe modelo para especificar um documento, esta classe contém quatro atributos declarados como private, juntamente com seus getters e setters que utilizaremos para recuperar e passar os valores, um construtor sem argumentos e um construtor com argumentos. Criaremos as próximas classes que serão quatro servlets para esta fazendo as operações no MongoDB.


@WebServlet("/InserirControler")
public class InserirControle extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // criando uma instancia de Pessoa
		Pessoa pessoa = new Pessoa();

		//Recuperando dados do JSP
		pessoa.setNome(request.getParameter("nome"));
		pessoa.setIdade(Integer.parseInt(request.getParameter("idade")));
		pessoa.setTelefone(request.getParameter("telefone"));
		pessoa.setEmail(request.getParameter("email"));

       // Criando a conexao com o mongo
		MongoClient conexao = new MongoClient();

		// Acessando a DataBase TCC
		MongoDatabase database = conexao.getDatabase("TCC");

		// Recuperando a coleção
		MongoCollection<Document> collection = database.getCollection("usuarios");

		// inserindo os dados
		collection.insertOne(
				new Document("Nome",pessoa.getNome())
				.append("Idade", pessoa.getIdade())
				.append("Info",
						new Document("Email",pessoa.getEmail())
						.append("Telefone", pessoa.getTelefone())
						)
				);
	}

}

Figura 57 – Servlet Incluir Fonte: Autoria Própria.

Como podemos observar a inclusão dos dados, assim como as outras operações serão praticamente a mesma demonstrada na sessão anterior utilizando java puro. A figura 58 exibe um arquivo chamado incluir.jsp, e nele que inserimos os dados e o nosso servlet irá recuperar os valores passados para inclui-los no mongoDB:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"     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>Inserir Pessoa</title>
</head>
<body>
<form action="InserirControler" method="post">
		   Nome: <input type="text" name="nome"/>
		   Idade: <input type="number" name="idade"/>
		   Telefone: <input type="text" name="telefone"/>
		   Email: <input type="text" name="email"/>

	   <input type="submit" value="Cadastrar Dados no MongoDB"/>
	</form>

</body>
</html>

Figura 58 – incluir.jsp Fonte: Autoria Própria.

CONSULTANDO DADOS COM SEVLET E JSP

A figura 59 demonstra o servlet para retorna os dados do banco e apresentar os mesmos na jsp. A figura 60 demonstra como fica a página que irá exibir os dados vindos da servlet.

@WebServlet("/ConsultarTodosControler")
public class ConsultarTodosControler extends HttpServlet {
     private static final long serialVersionUID = 1L;

     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

       RequestDispacher visao = null;

      // Criando a conexão
      MongoClient conexao = new MongoClient();

     // Acessando a DataBase TCC
     MongoDatabase dataBase = conexao.getDatabase("TCC");

     // Acessando a coleção
     MongoCollection<Document> collection = dataBase.getCollection("usuarios");

    // Configurando um atributo para JSP listar os dados
    request.setAttribute("listas",collection.find().iterator());

   // Retorna para a pagina listar.jsp
   visao = request.getRequestDispacher("listar.jsp");
   visao.forward(request,response);
  }
}

Figura 59 – Servlet Consultar Fonte: Autoria Própria.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" 	pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!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>Lista dos Dados</title>
</head>
<body>
<form action="ConsultarTodosControler" method="post">
<table align="center" border="4">
<tr bgcolor="gray">
<th>Nome</th>
<th>Idade</th>
<th>Telefone</th>
<th>Email</th>
</tr>
<c:forEach items="${listas}" var="usuario">
<tr>
<td>${usuario.nome}</td>
<td>${usuario.idade}</td>
<td>${usuario.telefone}</td>
<td>${usuario.email}</td>
</tr>
</c:forEach></table>
<input type="submit" value="consultar" />
</form>

    </body>
</html>

Figura 60 – listar.jsp Fonte: Autoria Própria.

ATUALIZANDO DADOS COM SEVLET E JSP

A figura 61, demonstra o uso o update para estarmos alterando 3 campos
a partir de um critério de busca pelo campo nome para o primeiro documento
da coleção, lembrando de importar a classe import static com.mongodb.client.model.Filters.*; para utilização da função eq. A página dealteração dos dados é semelhante ao da figura 58, bastando alterar alguns itens, conforme é mostrada na figura 62.

@WebServlet("/AlterarControler")
public class AlterarControler extends HttpServlet {
     private static final long serialVersionUID = 1L;

     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

      Pessoa pessoa = new Pessoa();

     // Recuperando dados do JSP
     pessoa.setNome(request.getParameter("nome"));
     pessoa.setIdade(Integer.parseInt(request.getParameter("idade")));
     pessoa.setTelefone(request.getParameter("telefone"));
     pessoa.setEmail(request.getParameter("email"));

      // Criando a conexão
      MongoClient conexao = new MongoClient();

     // Acessando a DataBase TCC
     MongoDatabase dataBase = conexao.getDatabase("TCC");

     // Acessando a coleção
     MongoCollection<Document> collection = dataBase.getCollection("usuarios");

    // Update dos Dados
    UpdateResult update = collection.updateOne(eq("Nome",pessoa.getNome());
        new Document("$set",
            new Document("Info.Email",pessoa.getEmail())
                .append("Info.Telefone",pessoa.getTelefone())
                .append("Idade",pessoa.getIdate())
            ));
    }
}

Figura 61 – Servlet Update Fonte: Autoria Própria.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"     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>Atualizar Pessoa</title>
</head>
<body>
<form action="AlterarControler" method="post">
		   Nome: <input type="text" name="nome"/>
		   Idade: <input type="number" name="idade"/>
		   Telefone: <input type="text" name="telefone"/>
		   Email: <input type="text" name="email"/>

	   <input type="submit" value="Alterar Dados no MongoDB"/>
	</form>

</body>
</html>

Figura 62 – update.jsp Fonte: Autoria Própria.

DELETANDO DADOS COM SEVLET E JSP

Por último criaremos o servlet responsável por deletar os dados através de uma busca, passando como parâmetro o campo nome como critério, lembrando de importar a classe import static com.mongodb.client.model.Filters.*; para utilização da função eq. Como demonstrada na figura 63 e a página deletar.jsp na figura 64.

@WebServlet("/DeletarControle")
public class DeletarControler extends HttpServlet {
     private static final long serialVersionUID = 1L;

     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

      Pessoa pessoa = new Pessoa();

     // Recuperando dados do JSP
     pessoa.setNome(request.getParameter("nome"));

      // Criando a conexão
      MongoClient conexao = new MongoClient();

     // Acessando a DataBase TCC
     MongoDatabase dataBase = conexao.getDatabase("TCC");

     // Acessando a coleção
     MongoCollection<Document> collection = dataBase.getCollection("usuarios");

    // Deletando dos Dados
    DeleteResult deleteResult = collection.deleteOne(eq("Nome",pessoa.getNome());
    }
}

Figura 63 – Servlet Deletar Fonte: Autoria Própria.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"     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>Deletar Pessoa</title>
</head>
<body>
<form action="DeletarControler" method="post">
		   Nome: <input type="text" name="nome"/>

	   <input type="submit" value="Alterar Dados no MongoDB"/>
	</form>

   </body>
</html>

Figura 64 – deletar.jsp Fonte: Autoria Própria.

Nesta sessão, abrangeu o uso da tecnologia Java EE trabalhando em conjunto com o MongoDB, através de Servlets e JSP para estarem interagindo e manipulando os dados entres os formulários web.

Como foi abordado ao longo dessas últimas sessões, a comunicação entre uma aplicação java seja ela web ou não com o Mongodb é bem simples de ser implementada e de fácil aprendizagem. Visto que não necessitamos utilizar SQL em nossos códigos e nem mesmo fazer uso de joins, tornando assim o desenvolvimento da aplicação bem rápida e pequena.

A próxima sessão será apresenta um framework Java de persistência especifico para bancos NoSQL, que irá facilitar ainda mais o desenvolvimento de muitas outras aplicações tanto web quanto aplicações para desktop.

REFERÊNCIAS

Marchioni, Francesco. MongoDB for Java Developers. Birmingham: Packt Publishing Ltd,2015.

 

 

COMUNICAÇÃO ENTRE JAVA E MONGODB

A Quinta postagem do blog será sobre a parte prática da  minha monografia de especialização em Desenvolvimento Java. Neste capitulo irá aprender a usar MongoDB juntamente com Java.

Boa Leitura.

Segundo o site da Oracle,

“Java é uma linguagem de programação e plataforma computacional lançada pela primeira vez pela Sun Microsystems em 1995. Existem muitas aplicações e sites que não funcionarão, a menos que você tenha o Java instalado, e mais desses são criados todos os dias. O Java é rápido, seguro e confiável. De laptops a data centers, consoles de games a supercomputadores científicos, telefones celulares à Internet, o Java está em todos os lugares!”

Segundo site do MongoDB (2016) para uma aplicação se comunicar com o MongoDB, precisamos de uma biblioteca cliente que chamamos de drivers. Estes drives lidam com toda a interação com o banco de dados em uma linguagem apropriada para a aplicação.

De acordo com Lennon (2012), “Drives oficiais disponíveis para C, C#, C++, Haskell, Java, JavaScript, Perl, PHP, Python, Ruby e Scala, com uma ampla variedade de drives suportados pela comunidade disponível para outras linguagens”.

OBTENDO O AMBIENTE DE TRABALHO

Nesta seção obteremos o nosso ambiente de desenvolvimento para trabalhar com o mongo no Java.

Inicialmente obteremos uma IDE para esta trabalhando com o Java, utilizaremos a plataforma eclipse, por ser considerada uma das melhores IDE para desenvolvimento na linguagem Java:

CRIANDO UM PROJETO JAVA COM MONGO

Iremos desenvolver uma simples aplicação Java utilizando o maven para esta obtendo o driver do mongo para sua conexão.

  • Vá em File → New → Maven Project e configure da conforme as figuras 43 e 44
43
Figura 43 – Novo Projeto Maven Fonte: Gerado pelo Eclipse
44
Figura 44 – Configuração do Projeto Maven. Fonte: Gerado pelo Eclipse.

Após seguir como demonstrada nas figuras 43 e 44, será gerada um projeto no eclipse chamado JavaMongo. Dentro deste projeto contém um arquivo chamado pom.xml, nele faremos umas configurações para o projeto bem como adicionar o driver do mongo para Java, como pode visto na figura 45:


<dependencies>
      <dependency>
             <groupId>org.mongodb</groupId>
             <artifactId>mongodb-driver</artifactId>
             <version>3.2.2</version>
      </dependency>
</dependencies>

<build>
      <plugins>
	     <plugin>
		     <artifactId>maven-compiler-plugin</artifactId>
		       <version>3.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
		      </plugin>
		</plugins>
	</build>

Figura 45 – Adicionado o MongoDrive Fonte: Gerado pelo Eclipse

Conforme a figura 45, no arquivo pom.xml, adicionamos o driver do mongo como dependência do projeto, que ao salva o arquivo o maven irá fazer o download da biblioteca especificada, assim com outras bibliotecas que o mongo drive necessita.

A partir deste momento daremos início à criação das classes Java para funcionar com o mongodb.

CRIANDO A CONEXÃO

Segundo o site do Mongodb, o MongoDrive fornece 5 maneiras de está se conectando nossa aplicação com o banco, como observado na figura 46:

import java.util.Arrays;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoDatabase;

public class ExemploConexao {

     // Primeiro método - Sem Parâmetro
     MongoClient primeiroExemplo = new MongoClient();

     // Segundo método - Somente ip/host
     MongoClient segundoExemplo = new MongoClient("localhost");

     // Terceiro método - ip/host e porta
     MongoClient terceiroExemplo = new MongoClient("localhost",27017);

     // Quarto método - Lista de Conexões
     MongoClient quartoExemplo = new MongoClient(
            Arrays.asList(
                    new ServerAddress("localhost",27017),
                    new ServerAddress("localhost",27018),
                    new ServerAddress("localhost",27019)
                  )
               );

     // Quinto método - conexão por URI
     MongoClientURI quintoExemplo = new MongoClientURI(
            "mongodb://localhost:27017,localhost:27018,localhost:27019");
     MongoClient quintoExemploURI = new MongoClient(quintoExemplo);

     // Acessando ou criando um dataBase / caso não exista, será criado.
     MongoDatabase dataBase = primeiroExemplo.getDatabase("TCC");
     System.out.println("Conectado com Sucesso!");
}

Figura 46 – Conexão com MongoDBB Fonte: Autoria Própria

Conforme visto na figura 46, foram exemplificadas as maneiras de está se conectando uma aplicação java. Ela é semelhante as conexões de bancos relacionais, principalmente na variável chamada quintoExemplo, onde é passada um endereço para sua conexão.

Ao executarmos esta classe, será criado automaticamente um banco de dados chamados TCC, caso o mesmo não exista.

INSERINDO DADOS NO BANCO

Para criar um documento, utilizamos a classe Document do mongo driver. No mongo driver, os métodos insertOne() e insertMany() estão presentes e são utilizados da mesma forma que no mongo shell e ainda podemos fazer uso de documentos incorporados.

Antes de estarmos inserindo documentos, precisaremos criar uma collection para esta armazenando os dados.

A figura 47, exemplifica a utilização tanto do método insertOne quanto do insertMany, acompanhado da criação da coleção:

      // Criando a conexão
      MongoClient conexao = new MongoClient();

      // Acessando a DataBase TCC
      MongoDatabase dataBase = conexao.getDatabase("TCC");

      /*
       * Criando ou recuperando uma coleção
       * caso não exista, será criado uma collection usuarios
       */
        MongoCollection<Document> collection = dataBase.getCollection("usuarios");

       // Inserindo usando o insertOne()
       collection.insertOne(
               new Document("Nome","Daniel Dias")
                   .append("Idade",25)
                   .append("Info",
                         new Document("Email","daniel.dias.analistati@gmail.com")
                   .append("Telefone","21 1234-5678)
                 )
            );

     // Inserindo usando o insertMany()
     List<Document> documentos = new ArrayList<Document>();

     for(int i = 0; i < 2; i++) {
          documentos.add(
                  new Document("Nome","Daniel Dias")
                  .append("Idade",25)
                  .append("Info",
                         new Document("Email","daniel.dias.analistati@gmail.com")
                  .append("Telefone","21 1234-5678)
                )
           );
       }

       collection.insertMany(documentos);

Figura 47 – Inserir Autoria Própria

CONSULTANDO OS DADOS

Para retornar os dados utilizamos também o método find() que foi descrito em capítulo sobre o mongo shell.

Segundo o site do MongoDB, O método find() retorna uma instância de findIterable, que nos fornece uma interface fluente para encadear ou controlar as operações do find. Usando o método iterator() podemos obter um iterador sobre o conjunto de documentos que combinavam com a consulta e repita.

Podemos também querer retornar apenas um documento, através do método first() sobre o find(). Isso é útil para consultas que só deve corresponder a um único documento. A figura 48 demonstra o uso desses dois métodos:

     // Consultando todos os documentos
     MongoCursor cursor = collection.find().interator();

     try {
            while(cursor.hasNext()) {
                System.out.println(cursor.next().toJson());
            }
       } finally {
             cursor.close();
        }

      // Consultando o primeiro documento
      Document primeiroDocumento = 
                 collection.find(eq("Nome","Daniel Dias")).first();
      System.out.println(primeiroDocumento);

Figura 48 – Consultando Autoria Própria

ATUALIZANDO OS DADOS

Assim com o insert, o mongo drive oferece os mesmos métodos de update do shell que são updateOne e updateMany(). Esses dois métodos recebem dois argumentos para esta atualizando o documento, um é o critério de busca para o documento e a outra é um documento que contém os novos dados para atualização. A Figura 49 demonstra o uso dois métodos de update:

     // Atualizando o primeiro documento
     collection.updateOne(eq("Nome","Daniel Dias"),
          new Document("$set",
               new Document("Nome","Daniel")
             )
         );

    // Atualizando muitos documentos
    UpdateResult updateResult = 
                 collection.updateMany(eq("Nome","Daniel Dias"),
                     new Document("$set",
                           new Document("Info.Email","daniel@daniel.com.br")
                        )
                );      

Figura 49 – Alterando Autoria Própria

DELETANDO DADOS

O mongo drive contém métodos para remover documento de uma coleção. Os métodos correspondentes são deleteOne e deleteMany, que tem o mesmo funcionamento do que foi apresentado no mongo shell.  A figura 50 demonstra o uso destes dois métodos:

     // Deletando o primeiro documento
     collection.deleteOne(eq("Nome","Daniel"));

    // Deletendo todos os documentos
    DeleteResult deleteResult = 
             collection.deleteMany(eq("Nome","Daniel Dias")); 

Figura 50 – Deletando Autoria Própria

Algo importante a ser citado, tanto na operação de update quanto de deletar, foi incluída uma chama ao método eq, este método é utilizado para uma condição de busca no documento.

Para que o eclipse o reconheça será preciso importar sua classe com essa declaração :

import static com.mongodb.client.model.Filters.*;

Nesta sessão, abrangeu os primeiros passos com mongoDB e o Java, que permitiu executar as mesmas operações do mongo shell, que foi visto no capítulo anterior.

A sessão seguinte, iremos cria uma aplicação web simples utilizando o Java EE que usa Mongodb como armazenamento. Será demonstrada como esta tecnologia pode alavancar um cenário do mundo real usando construções simples.

REFERÊNCIAS

IBM – Lennon, Joe. Explore o MongoDB. 2011. Disponível em: < https://www.ibm.com/developerworks/br/library/os-mongodb4/ > Acesso em: 11 de maio 2016.

MongoDB. MongoDB Drivers and Client Libraries. 2016. Disponível em: < https://docs.mongodb.com/manual/applications/drivers/ >. Acesso em: 10 de junho 2016.

Oracle. O que é a Tecnologia Java e porque preciso dela? 2016. Disponível em: < https://www.java.com/pt_BR/download/faq/whatis_java.xml >. Acesso em: 10 de junho 2016.

Mongo Shell

A Quarta postagem do blog será sobre a parte prática da  minha monografia de especialização em Desenvolvimento Java. Neste capitulo irá aprender o básico de MongoDB utilizando o Mongo Shell.

Boa Leitura.

Segundo Marchioni (2015), o shell Javascript do Mongodb lhe permite uma interação com a instância do banco de dados Mongo a partir da linha de comando. O shell é uma ferramenta trivial para desempenhar funções de administração, monitoramento de uma instancia em execução ou inserindo documentos.

Conforme citado na sessão anterior, para iniciar o MongoDB devemos executar o mongod, através do prompt, navegue para o diretório de instalação do MongoDB e execute o comando mongod.exe conforme mostrado na figura 11.

1
Figura 11 – Inciando o servidor MongoDB Fonte: Aplicação do Windows 8.

Após executar o comando o servidor MongoDB será iniciando conforme mostrado na figura 12:

2
Figura 12 – Servidor MongoDB iniciado Fonte: Aplicação do Windows 8

Conforme a figura 12, o servidor mongo foi iniciado na sua porta padrão 27017, é conforme citado o mesmo detectou a pasta data\db para armazenar os dados.

Para utilizarmos o Shell do Mongodb, devemos executar no mesmo diretório da figura 11 o comando mongo, para podermos está interagindo com o servidor mongo como é demostrado na figura 13 o shell executando após o comando inserido:

3
Figura 13 – Shell do MongoDB Iniciado Fonte: Aplicação do Windows 8.

Conforme a figura 13, foi iniciado o shell do Mongodb e automaticamente ele se conectou a um banco de dados existente por padrão da sua instalação. É a partir desse shell que poderemos está criando e excluindo banco de dados, coleções e também utilizando as operações de CRUD (Create, Read, Update e Delete) em nosso banco.

CRIANDO DATABASE, COLLECTION E DOCUMENTOS

Conforme citado nas sessões anteriores, o MongoDB cria data bases a partir de uma coleção de documentos (Collections), e essas collections são formadas por um agrupamento de documentos no formato JSON.

Banker, Kyle. et al (2016), explicam que o MongoDB divide as coleções em bancos de dados separados. E que ao contrário a sobrecarga habitual que os bancos de dados produzem no mundo sql, os bancos de dados no MongoDB são somente espaços de nome para distinguir entre as coleções. Para consultar no MongoDB, precisaremos saber o banco de dados (ou namespace) e a collection para qual documento se deseja consultar.

Conforme a figura 13, o mongo se conectou ao banco de dados chamado test, para trocar de banco devemos usar o seguinte comando:

 use nomedoBanco

Esse comando também é utilizado para a criação do banco de dados, caso ele não exista, após a execução do comando a seguinte mensagem é informada no shell, conforme a figura 14:

4
Figura 4 – Criando e Trocando de DataBase Fonte: Aplicação do Windows 8

Conforme a figura 14, foi o banco de dados que era test foi trocado pelo o nosso banco de dados que se chama OmegaWare, que no caso o mesmo foi criado, já que não existia.

Segundo Marchioni (2015), explica que para quem veio dos bancos de dados RDBMS, foi surpreendido que foi possível mudar para um novo banco de dados sem tê-lo criado anteriormente. O ponto é que a criação da base de dados no MongoDB não é necessária. Os bancos de dados e as coleções são criados primeiramente quando os documentos são realmente inseridos. Sendo assim, coleções se bancos de dados individuais podem ser criado em tempo de execução da mesma maneira que a estrutura de um documento é conhecido.

No MongoDB existe um comando que podemos usar para lista todas as bases de dados disponíveis que é:

  show dbs

Ao executarmos esse comando será mostrado uma lista de banco de dados disponíveis, conforme ilustrada na figura 15:

5
Figura 15 – Listando as DataBase Fonte: Aplicação do Windows 8.

Na figura 15 podemos ver no momento só estamos com uma base de dados disponível, a nossa base só estará disponível quando um documento já estiver inserido.

INSERINDO UM DOCUMENTO

Para inserirmos um documento, precisamos informar em qual collection esse documento será salvo.

Conforme ilustrado na figura 2, um documento é inserido no formato Json, como exemplo iremos inserir um documento em nossa base de dado recém-criada utilizando os métodos fornecido pelo MongoDB:

InsertOne(): Este método insere no mongo um único documento na sua base de dados como é demonstrada abaixo ao inserirmos um documento no nosso banco conforme a Figura 16:

 db.usuarios.insertOne(
    {
         Nome:"Daniel Dias dos Santos",
         Idade:25,
         Mensagem:"Inserindo um único documento no Mongo!"
    }
)

 Figura 16 – Inserindo com InsertOne Fonte: Autoria Pŕopria

Como visto na figura 16, foi criado um novo documento com 3 campos que são: Nome, Idade e Mensagem com os seus respectivos valores, onde o mesmo foram inseridos na sua collection (coleção) chamada usuários, que no caso essa collection não existia e foi criada após a inserção do documento. Em SQL essa mesma inclusão seria da seguinte forma:


INSERT INTO usuarios

(Nome,Idade,Mensagem)

VALUES

("Daniel Dias dos Santos",25,"Exemplo de Inserção SQL")

Figura 17 – Inserção única em SQL  Fonte: Autoria Pŕopria

  • InsertMany(): Este método insere no mongo múltiplos documentos em sua base de dados como é demonstrado na figura 18 ao inserirmos mais documentos na collection usuários:

db.usuarios.insertMany (

 [

     {

         Nome:"Daniel Dias dos Santos",

         Idade:25,

         Mensagem:"Documento 1"

     },

      {

            Nome:"MongoDB",

            Idade:7,

            Mensagem:"Documento 2"

     },

          {

              Nome:"Java",

             Idade:20,

             Mensagem:"Documento 3"

             }

     ]

)

Figura 18  – Exemplo de Inserção Múltiplos Documentos               Fonte: Autoria Pŕopria

Conforme visto na figura 18, ao utilizarmos o método insertMany(), foi inserido na mesma collection três documentos com os mesmos campos ,porem com valores diferentes. No caso essa mesma operação em SQL seria da seguinte forma:


INSERT INTO usuarios

(Nome,Idade,Mensagem)

VALUES

("Daniel Dias dos Santos",25,"Exemplo de Inserção SQL")

("MongoDB",7,"Exemplo de Inserção SQL")

("Java",20,"Exemplo de Inserção SQL")

Figura 19 – Inserção Múltipla em SQL Fonte: Autoria Pŕopria

  • Insert(): Este método também adiciona novos documentos a uma collection. Assim como o método insertOne() e insertMay() , ele pode tanto inserir um único documento quanto uma série de documentos, como exemplificado na figura 20 :
 db.usuarios.insert(
    {
         Nome:"Daniel Dias dos Santos",
         Idade:25,
         Mensagem:"Utilizando o Médoto insert()"
    }
)

Figura 20 – Inserindo com Insert Fonte: Autoria Pŕopria

CONSULTANDO DOCUMENTOS E CONHECENDO OUTRAS FUNÇÕES

Segundo a documentação do MongoDB, uma consulta tem como um alvo um conjunto especifico de documentos, onde as consultas seguem um critério ou condições, que identificam os documentos que o MongoDB tem que retorna aos clientes. Uma consulta pode ainda incluir uma projeção que especifica os campos dos documentos correspondentes para retornar. Possivelmente as consultas podem ser modificadas para impor limite, pular e ordenar.

Para podemos retornar nossos dados armazenados no banco, utilizamos o método find () para consultar, ela é semelhante ao comando select do SQL.

Chodorow (2013), explica que o método find retorna um subconjunto de documentos em uma coleção, de nenhum documento para toda a coleção. Os documentos retornados são determinados pelo primeiro argumento que encontrar que é um documento que especifica os critérios para a consulta.

Como exemplo iremos recuperar todos os valores do banco de dados utilizado a seguinte sintaxe db.nomeDaCollection.find() ,conforme é demonstrada na figura 21 :

7
Figura 21 – Exemplo de Consulta Utilizando find() Fonte: Autoria Pŕopria

Conforme a execução do comando, o resultado foi a exibição de todos os dados contido na collection usuários. Em SQL esse comando seria da seguinte forma select * from usuários, assim obtendo todos os registros da tabela no modelo relacional.

Um ponto a observar é que no resultado da consulta foi retornado um campo a mais chamado _id e que em nenhum momento quando inserimos os dados informamos o campo e o seu valor.

Conforme explica Banker, Kyle. Et al (2016), o campo _id pode ser visto como uma chave primaria do documento. Em que todos os documentos no MongoDB requerem um _id e se caso esse campo não estiver presente será criado automaticamente pelo MongoDB com o tipo ObejctID e adicionado ao documento ao mesmo tempo. Assim como nas chaves primarias de bancos relacionais, ObjectId também é única, porém pode definir o seu próprio _id em um documento, sendo que ObjectID é apenas um padrão do MongoDB.

Com o método find () podemos fazer busca mais específica como buscar por um determinado valor em nossa collection como apresentada na figura 22:

8
Figura 22 – Exemplo de Consulta Específica Fonte: Autoria Própria

Conforme o exemplo da figura 22, a consulta deve retornar todos os documentos de uma collection, onde campo Nome contém o valor Daniel Dias dos Santos, em SQL o seu comando seria:

SELECT * FROM usuarios WHERE Nome='Daniel Dias dos Santos'

“A exibição padrão do resultado de busca do MongoDB nem sempre é legível. Para resolver esse problema, basta adicionar no comando o sufixo..pretty()”.Boaglio (2015, p. 27).

Como exemplo a figura 23 demonstra como é o resultado da consulta sem o pretty() :

9
Figura 23 – Exemplo de Consulta sem pretty Fonte Autoria Própria

Como podemos observar, a consulta devolveu resultado de difícil compreensão. Para o resultado sair da mesma forma que a figura 22 usamos o pretty() da seguinte forma :

db.usuarios.find(
    {
        "Nome":"Daniel Dias dos Santos"
    }
).pretty()

Além dessa função, o método find apresenta outras funções como aponta Hows, David et al. (2015), onde explicam que o MongoDB incluir diversas funções de uso para um controle mais preciso de consultas, como o uso de funções sort, limit e skip como é demonstrada abaixo:

  • Sort(): A função sort() tem como objetivo classificar os resultados obtidos após as consultas. Podemos classificar em ordem crescente ou decrescente usando 1 ou -1, respectivamente. Essa função é equivalente a Order By no SQL e ele usa o nome da chave e o método de classificação como critérios como o exemplo a seguir:
db.usuarios.find().sort( 
  {
      "Nome":1
    }
)

Conforme o exemplo, resultado da classificação é baseada no valor chave que no caso Nome vai ter seu valor na ordem crescente. Este é a ordem padrão do método quando não passamos parâmetros, caso queremos resultado na ordem decrescente trocamos o valor 1 por -1, da mesma forma podemos trocar o valor chave por uma outra.

Limit(): Podemos está utilizando esta função para especificar o número máximo de resultados que queremos retornar. Ela requer apenas um parâmetro, ou seja, devemos passar um número dos resultados que desejamos obter, como por exemplo:

db.usuarios.find().limit(2)

Ao executarmos o comando, o resultado da consulta vai nos trazer dois documentos, pois especificamos um limite de retorno. Quando passamos o valor 0, o resultado é que todos os documentos serão retornados.

  • Skip(): Esta função nos permite salta o primeiros n documentos em uma coleção, como exemplo o comando a seguir ira saltar 2 documentos e nossa base :
db.usuarios.find().skip(2)

Como resultado, irá retornar somente um documento, visto que pulamos dois, caso existisse mais documentos ele irá trazer todos os documentos da coleção usuários e irá ignorar os 2 primeiros.

Ainda de acordo com os autores citado, o Mongodb não seria poderoso, se não fosse a sua capacidade de esta combinando estes comandos. Podemos combinar praticamente qualquer função e usando em conjunto com outras funções, conforme o exemplo:

db.usuarios.find()
.sort(
    {
         Idade:-1
   }
).limit(10).skip(20)

Esse exemplo limitou o resultado até 10, saltando os 20 primeiros documentos e classificando a Idade em ordem decrescente.

Até o momento, nossa consulta tem retornado todos os documentos da nossa collection, e que nem sempre iremos querer retornar todos, por este motivo, o MongoDB fornece um método findOne() para retornarmos um único documento que queremos e ainda podemos fazer buscas especificas para obtermos resultados mais precisos. A sintaxe do do findOne é idêntica a função find ():

db.nomeDaCollection.findOne(query,projeção)

Ao executarmos esse comando, será retornado o primeiro documento dentro da coleção de acordo com sua ordem natural que reflete na ordem do documento no disco. Caso nenhum documento satisfaça a consulta, o método retorna null.

Como exemplo deste método, iremos fazer uma consulta especificando os campos que queremos retornar conforme a figura 24, onde localiza na coleção usuários e retorna somente o nome, idade e o _id:

10
Figura 24 – Exemplo do findOne() Fonte : Autoria Própria

Uma outra função importante é o count(),que tem a finalidade de contar quantos documentos têm em uma coleção específica, no exemplo, será retornado da base de dados 3 documentos armazenados na collection:

db.usuarios.count()

Boaglio (2015), listas algumas operações de busca, que são:

11
Tabela 2 – Operações de Busca Fonte: Boaglio (2015,p.46)

ATUALIZANDO DOCUMENTOS

Assim como o insert, o MongoDB oferece 4 métodos de atualização dos dados que serão demonstrados a sua utilização:

  • updateOne(): Este método nos permite atualizar somente um único documento.
12
Figura 25 – Exemplo de UpdateOne() Fonte: Autoria Própria

Conforme a figura 25, esta operação de atualização sobre a collection usuários, definiu uma nova mensagem para o campo Mensagem para o primeiro documento que corresponda o filtro de idade maior que 7. Esse comando em SQL seria desta forma:


UPDATE usuarios
SET Mensagem = 'Exemplo de SQL'
WHERE Idade > 7
LIMIT 1

Figura 26 – Exemplo de Update SQL – Fonte: Autoria Própria

  • updateMany(): Este método nos permite atualizar múltiplos documentos em nossa collection.
13
Figura 27 – Exemplo do updateMany() Fonte: Autoria Própria

Na figura 27, foi feita a mesma operação da figura 25, sendo que trocamos o método updateOne para updateMany, que ao executar o comando, será atualizada o campo Mensagem de todos os documentos onde o filtro corresponda a idade maior que 7.

Este comando em SQL seria da mesma forma da figura 26, só retirando o Limit 1 do comando.

  • replaceOne(): Este método substitui um único documento na collection sobre o filtro.
14
Figura 28 – Exemplo de replaceOne() Fonte: Autoria Próṕria

Esta operação de substituição na collection usuários, substitui o primeiro documento que corresponde ao filtro de Nome que é Daniel Dias dos Santos com um novo documento, como podemos observar na figura 28. Que no caso tanto o Nome quanto a Mensagem foram modificadas, menos a Idade, já que a deixamos com o mesmo valor. Em SQl este comando seria da seguinte forma:


UPDATE usuarios
SET Nome = 'Daniel' Idade = '25' Mensagem = 'Exemplo SQL'
WHERE Nome  = 'Daniel Dias dos Santos'
LIMIT 1

Figura 28 – Exemplo de Update SQL – Fonte: Autoria Própria

  • Update(): Segundo Hows, David et al. (2015), O Mongo fornece a função update() para esta realizando as alterações dos dados. Esta função recebe três argumentos principais que são critérios, objNew e as opções.

Onde os critérios permitem especificar a consulta que seleciona o registro na qual desejamos atualizar. Utilizamos o objNew para especificar a informação atualizada ou podemos fazer uso de um operador para fazer isso.

Já o argumento de opções, permite que especificamos as suas opções ao atualizar o documento, e que possui dois valores possíveis que são: upsert e multi.

A opção upsert permite especificar se a atualização dever ser um upsert, ou seja, ele diz ao MongoDB para atualizar o registro se ele existir e cria-lo se isso não acontecer.

A opção multi, permite especificar se todos os documentos correspondentes devem ser atualizados ou se apenas o primeiro (ação padrão).

15
Figura 30 – Exemplo update() Fonte: Autoria Própria

O exemplo da figura 30, irá atualizar o campo Mensagem de todos os documentos em que a idade for maior que 7.

DELETANDO DADOS

Assim como o insert e o update o MongoDB oferece 3 métodos de deletar os dados, que serão demonstrados a sua utilização:

  • deleteOne(): De acordo com Hows, David et al. (2015), se desejarmos apagar um único documento, precisaremos especificar os critérios que irá usar para encontrar o documento. Segundo eles, uma boa abordagem é a realização de um find () primeiro, pois dessa maneira garante que os critérios utilizados são específicos ao seu documento.

Neste exemplo utilizaremos as duas formas. A primeira é utilizando a abordagem proposta pelos autores e a segunda passando os critérios:

16
Figura 31 – Exemplo 1 de deleteOne() Fonte: Autoria Própria

Conforme a figura 31, utilizamos o método findOne() para buscar um único documento com critério passado e armazenamos o seu valor em uma variável de nome deletarPorBusca. Logo em seguinte utilizamos o método deleteOne() passando como parâmetro a variável deletarPorBusca. Ao executar o comando o documento será deletado da nossa collection usuários. O segundo exemplo é passando critérios:

17
Figura 32 – Exemplo 2 de deleteOne() Fonte: Autoria Própria

A figura 32, utilizamos o método deleteOne() passando parâmetro. Esta operação ira excluir o primeiro documento em que a Idade é 20.  Em SQL este comando seria da seguinte forma:

DELETE FROM usuarios WHERE Idade = '20' LIMIT 1

Figura 33 – Exemplo de delete SQL – Fonte: Autoria Própria

  • deleteMany(): Assim como as outras, esta função deleta múltiplos documentos em uma collection, conforme a figura 34 e a sua forma em SQL é semelhante ao da figura 33:
18
Figura 34 – Exemplo de deletaMany() Fonte : Autoria Própria
  • Remove(): Este função aceita critério de consulta para determinar quais os documentos para remover, bem como um documento de opções que afeta ao seu comportamento, tais como a opção justone para remover apenas um único documento:
19
Figura 35 – Exemplo de remove() Fonte: Autoria Própria

O comando executando na figura 35, irá deletar todos os documentos que seguir o critério passado, onde a idade é igual a 25.

Hows, David et al. (2015), explicam que pode haver necessidade de está apagando uma coleção inteira, para isso temos duas funções, que são drop() e a própria remove(). Segundo eles, a utilização do remove () é mais lenta do que a drop(), pois todos os índices serão mantidos dessa forma. Com o drop(), será mais rápido se necessitamos remover todos os dados ,bem como todos os índices de uma coleção. O exemplo da figura 36 remove toda coleção usuários, incluindo os documentos:

20
Figura 36 – Exemplo de drop() Fonte: Autoria Própria

A função drop() retorna true ou false , dependendo se a operação foi concluída com êxito. Da mesma forma que podemos está apagando uma collection, podemos também está deletando um banco de dados do MongoDB com a função dropDatabase() ,como na figura 37 :

21
Figura 37 – Exemplo de dropDatabase() Fonte : Autoria Próṕria

No exemplo, foi removido o banco de dados em estávamos trabalhando atualmente.

ARRAYS

Marchioni (2015), explica que o MongoDB possui uma linguagem de consulta rica que suporte armazenamento e acesso a documento como array. A grande coisa sobre matrizes em documentos é que MongoDB entende sua estrutura e sabe como chegar dentro das matrizes para executar as operações em seu conteúdo. Isso nos permite consultar em matrizes e construir índices utilizando seu conteúdo.

Como exemplo, será criado um par de documentos que contém um array de itens conforme a figura 38:

db.usuarios.insert(
  [
      {
         Desenvolvedores:["Daniel","James","Bill"]
     },
        {
          Desenvolvedores:["Daniel","Lisa","Paul"]
       }
  ]
)

Figura 38 – Exemplo de Arrays – Fonte: Autoria Própria

Faremos uma consulta sobre a matriz para encontrar em Desenvolvedores o que contem Bill armazenado:

22
Figura 39 – Exemplo de Consulta por Arrays Fonte: Autoria Própria

Podemos também combinar arrays usando mais de um elemento, utilizando $all. Ela permite que combinarmos com uma lista de elementos como exemplificado na figura 40:

23
Figura 40 – Exemplo de Consulta por Combinação de elementos. Fonte: Autoria Própria

DOCUMENTOS INCORPORADOS

Segundo Marchioni (2015), podemos utilizar um documento como um valor para uma chave. Isso que chamamos de um documento incorporado.

Documentos incorporados podem ser usados para esta organizando os dados de uma forma mais natural do que apenas uma estrutura plana de pares chave/valor. Desta forma combina bem com a maioria das linguagens orientada a objeto, que contém uma referência para outra estrutura na sua classe.

Na figura 41 criaremos uma estrutura, que é atribuído a uma variável no mongo shell:

usuario = {
    "_id":1234,
    Nome:"Daniel",
    Cursos: [
              {
                 Titulo:"Java Básico",
                 Ano:2011,
                Instituição:"Prime Cursos"
             },
                 {
                     Titulo:"SQL Básico",
                     Ano:2012,
                    Instituição:"Soft Blue"
                }
      ]
}

Figura 41 – Exemplo de Documento incorporado – Fonte: Autoria Própria

Tendo definido a nossa variável, iremos inseri-la em nossa collection usuários utilizando o insert() com o nome da variável como parâmetro.

Conforme a figura 41, criamos um único documento contendo três campos, e um desses campo contém um array contendo dois documentos incorporado em seu conteúdo.

Para podemos consultar o subdocumento, usamos a notação de ponto, conforme o exemplo da figura 42, podemos escolher a lista de cursos cujo o ano é 2011 utilizando o critério Cursos.Ano:

24
Figura 42 – Exemplo de Consulta de SubDocumento Fonte: Autoria Própria

Neste capítulo foram apresentados exemplos práticos de uso do mongoDB pelo shell com as suas operações básico para se está trabalhando com esse banco NoSQL.

No próximo capítulo será apresentado o uso prático do MongoDB em conjunto com a tecnologia Java através do MongoDB Java Drive.

REFERÊNCIAS

Banker, Kyle; et al. MongoDB in Action, Second Edition. Shelter Island: Manning, 2016.

Boaglio, Fernando. MongoDB construa nova aplicações com nova tecnologias. São Paulo: Casa do Código, 2015.

Chodorow, Kristina. MongoDB The Definitive Guide, 2nd Edition. Gravenstein Highway North: O’Reilly, 2013.

Hows, David; et el. The Definitive Guide to MongoDB A complete guide to dealing with Big Data using MongoDB, Third Edition . New York, NY: Apress, 2015.

Marchioni, Francesco. MongoDB for Java Developers. Birmingham: Packt Publishing Ltd,2015.

MongoDB. Introduction to MongoDB. 2016. Disponível em: < https://docs.mongodb.com/manual/introduction />. Acesso em: 11 de maio 2016.

Obtendo e Configurando o MongoDB em seu Ambiente

A Terceira postagem do blog será sobre a minha monografia de especialização em Desenvolvimento Java. Neste capitulo descrevo o assunto sobre o processo de configuração do MongoDB.

Boa Leitura.

Felizmente a instalação do MongoDB é muito simples e rápida, porem requer algumas configurações, principalmente ambientes onde o sistema operacional seja Windows.

MongoDB é multiplataforma, ou seja, podemos instalar o mongo em qualquer plataforma, de acordo com a tabela 1:

captura-de-tela-de-2016-12-05-23-21-38
Tabela 1 – Plataforma Aceitas Fonte: Documentação do MongoDB

Nesse momento, podemos dar início a instalação do MongoDB em novo ambiente, optaremos pela instalação do Windows, pela sua simplicidade no processo de instalação.

MongoDB Server

Em https://www.mongodb.com/downloadcenter?jmp=nav#community, iremos adquirir a versão MongoDB Community Server 3.2.6 para Windows na caixa de opções iremos selecionar a primeira que é mostrada Windows Server 2008 R2 and later, With SSL support. Mesmo estando explicitamente Windows Server, não é necessário ter essa versão do sistema Operacional, o MongoDB também funciona em sistemas operacionais Windows 7,8 e 10 de 64 bit, visto que a versão de 32 bit está depreciada.

Para instalar, basta dar clique duplo no arquivo para iniciar o processo de instalação conforme as figuras 5 a 9:

Na figura 5, clique em next para prosseguir para a próxima tela:

tela-5
Figura 5 – Tela de Instalação do MongoDB Fonte: Instalador do MongoDB

Na figura 6, marque a caixa para aceitar o termo da licença e clique em next para prosseguir.

tela-6
Figura 6 – Tela de licença do MongoDB Fonte: Instalado do MongoDB.

Na figura 7, temos duas opções a completa e a customizada.

  1. Na completa ela irá instalar todos os recursos do MongoDB
  2. Na customizada, podemos escolher o que queremos instalar.

Escolhida a opção, clique em next para continuar.

tela-7
Figura 7 – Tela de opção de Instalação do MongoDB. Fonte: Instalador do MongoDB.

Na figura 8, irá iniciar o processo de instalação do MongoDB, a instalação é
bem rápida.

tela-8
Figura 8 – Tela de processo de Instalação do MongoDB Fonte: Instalador do MongoDB

Na figura 9, concluímos o processo de instalação do MongoDB, clique em Finish para fechar a janela.

tela-9
Figura 9 – Finalização de Instalação do MongoDB Fonte : Instalador do MongoDB

Após concluirmos a instalação, a sua pasta de se encontra no seguinte caminho: C:\Program Files\MongoDB\Server\3.2\bin, dentro desta pasta se encontra os arquivos necessário para se está utilizando o mongo que são:

  • mongod: É o executado para iniciar o servidor mongoDB. Ele lida com solicitações de dados, gerencia o acesso de dados e executa as operações de estão de background.
  • mongo: É uma interface JavaScript Shell interativa para o mongoDB, ela fornece uma interface poderosa para administradores de sistemas, como como uma maneira para os desenvolvedores testa a consulta e as operações diretamente com o banco de dados. O MongoShell é semelhante ao sql plus da Oracle e shell do MySQL.

Será necessário criar uma pasta com um subpasta para o mongo armazenar os dados, essa pasta deverá criada na raiz do sistema, que por padrão o MongoDB irá procurar pela pasta \data\db, devemos criar essa pasta conforme mostrando na figura 10, que no caso foi criada no disco C:

tela-10
Figura 10 – Criação da pasta de dados do MongoDB Fonte: Windows 8.

Contudo podemos dar início a utilização do MongoDB a partir do Shell para podemos nos familiarizar com a nova tecnologia para então podemos está utilizando em conjunto com a linguagem de programação Java, onde poderemos ver que o processo de utilização com Java também é fácil de ser implementada, pois é semelhante a utilização com bancos relacionais, que também se faz uso de conector JDBC e assim como uso de frameworks de persistência apropriados para bancos NoSQL.

REFERÊNCIAS

MongoDB. Install MongoDB. 2016. Disponível em: < https://docs.mongodb.com/manual/installation/&gt; Acesso em: 11 de maio 2016.