Spring com MongoDB
Tags: java, spring, mongodb, tutorial
Published: 2021-11-22 12:17:52

Hoje em dia com tantas opções para armazenamento de informações para necessidades diferentes, saber como trabalhar com estas opções é importante.

Por isso decidi escrever esse tutorial de como criar uma aplicação em java utilizando um banco de dados NoSQL. 
E para isto criei uma POC para ilustrar utilizando as tecnologias, java 8, spring(spring data mongodb) e o mongoDB.

Decidi por dividir o tutorial e iniciar este com a integração da nossa aplicação com a base de dados.

Vamos iniciar baixando o spring no [Spring Initializr](https://start.spring.io/). E lá já podemos especificar as dependências necessárias.

![fing. 1 - print com as dependências](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uk8y3x7p3g3wjwhoz5j6.png)
fig. 1 - print com as dependências
 
Aqui selecionei o **Spring Web**, já que pretendo montar aqui uma aplicação web e ja vem com o *Spring MVC* além do servidor web *Apache Tomcat*, **Thymeleaf** para ser nosso template e por último o **Spring Data MongoDB** que vai nos auxiliar a guardar e recuperar nossa informação.

Agora vamos ao MongoDB e aqui invés de subir em um docker container ou até instalar localmente eu optei por usar a versão [cloud](https://www.mongodb.com/cloud) e lá podemos utilizar a versão trial. 

![print mongodb cloud](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xmpf2v316mrxwenspebk.png)
 fig. 2 - print mongodb cloud

Esse [doc](https://docs.atlas.mongodb.com/getting-started/) da um passo a passo para: 

* criação da conta grátis 
* do cluster
* adicionar seu IP para acesso ao cluster
* criação de um usuário para o cluster

O doc é bem explicado e tranquilo de seguir, porém só encontrei a versão em inglês.

Com os passos acima realizados é hora de testar conectando nossa aplicação ao cluster recém criado.

Precisamos recuperar nossa string de conexão, para isto acesse seu cluster e no dash clique em _Connect_

![dash do cluster para pegar o host](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q7cc2mq0i22357jjhx5c.png)
 fig. 3 - dash do cluster para pegar o host

E no box que vai abrir selecione _Connect your application_

![box com opções de conexão](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1tq876kxactsaj8dpzb0.png)
 fig. 4 - box com opções de conexão

E aqui vamos selecionar o driver para a conexão e neste caso *Java* e a versão mais recente dele e logo abaixo já temos nossa string de conexão.

![box para seleção de driver e string de conexão](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9eqyu05xq9dewueua2v4.png)
 fig. 5 - box para seleção de driver e string de conexão

Na fig. 3 no dash do cluster podemos criar nosso database clicando em *Browse Data* que irá abrir uma tela com nossas collections.

![box para criar database e collection](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o9lmornqnwnckvrnj2mn.png)
   fig. 6 - box para criar database e collection

Clicando em _Create Database_ irá abrir um box para definirmos o nomes da database e collection.

Certo agora podemos definir estar informações em nossa aplicação, no arquivo _application.properties_ dentro de resources.

![localização do arquivo application.properties](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ny66dslczlx37m22ekgr.png)
 fig. 7 - localização do arquivo application.properties

Aqui vamos definir as properties necessárias para conectar a nossa database.
```
spring.data.mongodb.uri={aqui nossa string de conexão}
spring.data.mongodb.database={aqui o nome da database criada}
```
E ao iniciar nossa aplicação vamos receber uma mensagem similar a esta.

![mensagem de conexão criada com o mongodb](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c3xgv8av9zutfvg3qw9h.png)
 fig.8 - mensagem de conexão criada com o mongodb

Por último podemos já interagir com nossa database e collection recém-criadas, inciando com a criação de um repository.

Dentro do nosso package podemos criar um diretório novo chamado _repository_ e dentro dele nossa _interface_ a _PetRepository_ esta por sua vez vai extender a MongoRepository que traz os métodos como _insert()_, _findAll()_, _saveAll()_ para o comunicação com nosso Mongo.

```
@Repository
public interface PetRepository extends MongoRepository<Pet, String> {
}
```
Adicionamos a anotação _@Repository_ para o spring saber do que se trata e além disso passamos para nosso MongoRepository a entity Pet que vamos criar agora.

Aqui vamos fazer uma simples Entity com o identificador id(o MongoDB precisa deste) com a anotação _@Id_, name, age e type do pet que vamos manipular. Anotamos a entidade com o nome da collection que vamos mapear.

```
@Document(collection="pets")
public class Pet {

    @Id
    private String id;

    private String name;
    private int age;
    private String type;

// todos os getters e setters
}
```
Só um detalhe para o atributo _type_ que aqui pretendo criar uma classe para ele, porém para agilizar o teste fiz com tipo String.   
Com isso já podemos criar nosso service que vai chamar os métodos do nosso repository. Criamos um pacote chamado service e dentro dele nosso _PetService_ com um método para retornar todos os pets existentes. 
Anotamos a classe com a anotação _@Service_ e injetamos nossa dependência PetRepository com a anotação _@Autowired_ e criamos o nosso método _findAll()_ 

```
@Service
public class PetService {

    @Autowired
    private PetRepository repository;

    public List<Pet> findAll() {
        return repository.findAll();
    }
}
```
E agora para ver nossos pets cadastrados vamos criar uma controller para através da nossa service resgatar nossos pets. No código abaixo da para ver que algumas partes são similares a nossa service, mudando alguns detalhes como a injeção que desta vez é nossa _PetService_ e as anotações usadas, como a _@RequestMapping_ para mapear as requisições recebidas. E por último recebemos como parâmetro um Model para setar o atributo para nossa _view_

```
@Controller
@RequestMapping("/pets")
public class PetController {

    @Autowired
    private PetService petService;

    @RequestMapping("/list")
    public String list(Model model) {
        final List<Pet> petList = petService.findAll();
        model.addAttribute("pets", petList);

        return "pets/list";
    }
}
```
Só precisamos criar nosso arquivo html em um diretório dentro de resources > templates chamados pets. Aqui fiz um html bem simples, apenas para listar o nome e idade dos nossos pets e neste html como estamos usando a biblioteca thymeleaf usei as propriedades da mesma para iterar e exibir os itens.

```
<body>
    <div id="listPets">
        <h3>List all pets</h3>
        <table>
            <thead>
            <tr>
                <td>Name: </td>
                <td>Age: </td>
            </tr>
            </thead>
            <tr th:each="pet : ${pets}">
                <td><span th:text="${pet.name}"></span></td>
                <td><span th:text="${pet.age}"></span></td>
            </tr>
        </table>
    </div>
</body>
```
E quando rodarmos temos uma página sem itens. E por quê? Porque não adicionamos nenhum item e agora é uma boa oportunidade para também testarmos o insert.

Na nossa entity criei um construtor, para facilitar a atribuição da nossa entidade, passando o _name_, _type_ e _age_.

```
public Pet(String name, String type, int age) {
     this.name = name;
     this.type = type;
     this.age = age;
}
```
No service criamos um novo método chamado save que recebe a entidade Pet e chamamos nosso _PetRepository_ chamando o método _save()_ passando nosso pet.

```
public void save(Pet pet) {
     repository.save(pet);
}
```
Nossa controller vai chamar o _save()_ da nossa _PetService_
passando um novo Pet e retornando uma string com o html que vamos criar

```
@GetMapping("/populate")
public String populateWithPets() {
     petService.save(new Pet("nina", "cat", 7));
     return "pets/populate";
}
```
E por fim criamos um html, aqui pode ser vazio, em templates > pets, que já tinhamos criado anteriormente. 

E se tudo deu certo depois de acessar nossa url _pets/populate_ podemos conferir nosso pet recém salvo em _pets/list_ ou até mesmo dentro do nosso cluster la no mongodb atlas

![pet salvo no mongodb](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nkcnspkzqdkgo71pe5sk.png)
 fig. - 9 pet salvo no mongodb

E para esta primeira parte do tutorial creio ser o suficiente, pretendo continuar com o tutorial utilizando esta app para nos auxiliar. Se tiverem alguma dúvida, dificuldade ou verem algum ponto que poderia ter feito de outra maneira só comentarem para interagirmos.     

Obrigado e nos vemos na continuação =)