Bem-vindo ao exemplo do Spring Boot MongoDB. O Spring Boot é a maneira mais fácil de iniciar um projeto Spring rapidamente e o MongoDB é o banco de dados NoSQL mais popular. Vamos ver como integrar o Spring com o banco de dados MongoDB.
Spring Boot MongoDB
Precisamos das seguintes APIs para trabalhar com o Spring Boot e o banco de dados MongoDB.
- Spring Data MongoDB
- Spring Boot
Existem duas abordagens pelas quais podemos nos conectar ao banco de dados MongoDB – MongoRepository
e MongoTemplate
. Vamos tentar estabelecer o que uma API oferece sobre a outra e quando você deve escolher uma delas para o seu caso de uso. Vamos usar a ferramenta Spring Initializr para configurar rapidamente o projeto. Então, vamos começar.
Configuração do Projeto Spring Boot MongoDB
Vamos usar a ferramenta Spring Initializr para configurar rapidamente o projeto. Vamos usar apenas duas dependências conforme mostrado abaixo: Baixe o projeto e descompacte-o. Em seguida, importe-o para o seu IDE favorito – Eclipse ou IntelliJ IDEA.
Dependências do Maven
Embora já tenhamos concluído a configuração com a ferramenta, se você deseja configurá-la manualmente, utilizamos o sistema de construção Maven para este projeto e aqui estão as dependências que utilizamos:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.journaldev.spring</groupId>
<artifactId>spring-boot-mongodb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-boot-mongodb</name>
<description>Spring Boot MongoDB Example</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Certifique-se de usar a versão estável do Spring Boot do repositório central do Maven.
Classe de Modelo do MongoDB do Spring Boot
Temos uma classe de modelo simples User.java
.
package com.journaldev.bootifulmongodb.model;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document
public class User {
@Id
private String userId;
private String name;
private Date creationDate = new Date();
private Map<String, String> userSettings = new HashMap<>();
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public Map<String, String> getUserSettings() {
return userSettings;
}
public void setUserSettings(Map<String, String> userSettings) {
this.userSettings = userSettings;
}
}
APIs do MongoDB do Spring Boot
Teremos as seguintes funcionalidades e interações com o banco de dados em nosso aplicativo.
- Obter todos os usuários
- Obter um usuário com ID
- Obter configurações do usuário
- Obter uma chave específica do mapa
- Adicionar/Atualizar configuração do usuário
Spring Data MongoDB – MongoRepository
Agora vamos usar o repositório Spring Data MongoDB para acessar nossos dados. O Spring Data MongoRepository nos fornece funcionalidades comuns que podemos facilmente integrar e utilizar. Vamos definir nossa interface de repositório.
package com.journaldev.bootifulmongodb.dal;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import com.journaldev.bootifulmongodb.model.User;
@Repository
public interface UserRepository extends MongoRepository<User, String> {
}
Definindo propriedades do MongoDB
Antes de configurarmos nosso controlador, é importante que estabeleçamos uma conexão com uma instância local do MongoDB. Vamos usar as propriedades do Spring Boot para fazer isso.
# Configuração do MongoDB local
spring.data.mongodb.authentication-database=admin
spring.data.mongodb.username=root
spring.data.mongodb.password=root
spring.data.mongodb.database=user_db
spring.data.mongodb.port=27017
spring.data.mongodb.host=localhost
# Configuração do aplicativo
server.port=8102
spring.application.name=BootMongo
server.context-path=/user
Assim, o aplicativo será executado na porta 8102 e se conectará a uma instância local do MongoDB com as credenciais fornecidas. Se você tiver uma instância local sem autorização habilitada, pode simplesmente remover as três primeiras linhas de configuração.
Definindo o Controlador Spring
Vamos finalmente passar para a criação de nossa classe de controlador.
package com.journaldev.bootifulmongodb.controller;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.journaldev.bootifulmongodb.dal.UserRepository;
import com.journaldev.bootifulmongodb.model.User;
@RestController
@RequestMapping(value = "/")
public class UserController {
private final Logger LOG = LoggerFactory.getLogger(getClass());
private final UserRepository userRepository;
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
Acabamos de Autowired a dependência da interface do repositório e vamos usar isso a seguir.
Definindo as APIs
Para as funcionalidades que mencionamos, agora faremos APIs e acessaremos a dependência do userRepository, que internamente usará a API Spring Data MongoRepository. Observe que não precisamos escrever nenhum código de interação com o banco de dados na interface, pois o Spring Data faz tudo por nós.
Obtendo todos os usuários
@RequestMapping(value = "", method = RequestMethod.GET)
public List<User> getAllUsers() {
LOG.info("Getting all users.");
return userRepository.findAll();
}
findAll()
é apenas um método que o Spring Data MongoRepository fornece internamente.
Obtendo um usuário por ID
Agora, vamos obter um usuário específico com um ID.
@RequestMapping(value = "/{userId}", method = RequestMethod.GET)
public User getUser(@PathVariable String userId) {
LOG.info("Getting user with ID: {}.", userId);
return userRepository.findOne(userId);
}
findOne()
é apenas um método que o Spring Data MongoRepository fornece internamente para obter um objeto por um ID.
Adicionando um novo usuário
Vamos adicionar um novo usuário na função abaixo.
@RequestMapping(value = "/create", method = RequestMethod.POST)
public User addNewUsers(@RequestBody User user) {
LOG.info("Saving user.");
return userRepository.save(user);
}
Obtendo configurações do usuário
Agora que adicionamos dados de exemplo no banco de dados, vamos tentar extrair uma parte deles.
@RequestMapping(value = "/settings/{userId}", method = RequestMethod.GET)
public Object getAllUserSettings(@PathVariable String userId) {
User user = userRepository.findOne(userId);
if (user != null) {
return user.getUserSettings();
} else {
return "User not found.";
}
}
Obtendo uma configuração de usuário específica
@RequestMapping(value = "/settings/{userId}/{key}", method = RequestMethod.GET)
public String getUserSetting(@PathVariable String userId, @PathVariable String key) {
User user = userRepository.findOne(userId);
if (user != null) {
return user.getUserSettings().get(key);
} else {
return "User not found.";
}
}
Observe na consulta acima que obtivemos o objeto do usuário, depois extraímos o mapa completo de configuração (que poderia conter milhares de objetos) e, finalmente, obtivemos nosso próprio valor. Isso é uma desvantagem para a consulta do Spring Data quando a usamos como API direta.
Adicionando uma nova configuração de usuário
Vamos tentar adicionar alguns dados a um usuário existente:
@RequestMapping(value = "/settings/{userId}/{key}/{value}", method = RequestMethod.GET)
public String addUserSetting(@PathVariable String userId, @PathVariable String key, @PathVariable String value) {
User user = userRepository.findOne(userId);
if (user != null) {
user.getUserSettings().put(key, value);
userRepository.save(user);
return "Key added";
} else {
return "User not found.";
}
}
Com todo o código que escrevemos, fica claro que não precisamos escrever uma única linha de código para acessar o banco de dados, além de definir a interface do repositório e injetar a dependência. Esta é a facilidade que a API Spring Data MongoRepository
nos oferece, mas também tem algumas desvantagens. Vamos elaborar isso quando tivermos definido também a versão do MongoTemplate
. Vamos começar com isso também.
Spring Data MongoDB – MongoTemplate
Aqui estaremos definindo as consultas ao banco de dados utilizando o MongoTemplate. Com o MongoTemplate, você verá que temos muito mais controle granular sobre o que consultamos e quais dados estão incluídos nos resultados.
Definindo a interface DAL
Para fornecer um contrato na camada de acesso ao banco de dados, começaremos definindo uma interface que funcione exatamente como nossos métodos internos do Spring Data.
package com.journaldev.bootifulmongodb.dal;
import java.util.List;
import com.journaldev.bootifulmongodb.model.User;
public interface UserDAL {
List<User> getAllUsers();
User getUserById(String userId);
User addNewUser(User user);
Object getAllUserSettings(String userId);
String getUserSetting(String userId, String key);
String addUserSetting(String userId, String key, String value);
}
Implementando a interface DAL
Vamos seguir em frente e definir esses métodos.
package com.journaldev.bootifulmongodb.dal;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import com.journaldev.bootifulmongodb.model.User;
@Repository
public class UserDALImpl implements UserDAL {
@Autowired
private MongoTemplate mongoTemplate;
@Override
public List getAllUsers() {
return mongoTemplate.findAll(User.class);
}
@Override
public User getUserById(String userId) {
Query query = new Query();
query.addCriteria(Criteria.where("userId").is(userId));
return mongoTemplate.findOne(query, User.class);
}
@Override
public User addNewUser(User user) {
mongoTemplate.save(user);
// Agora, o objeto usuário conterá o ID também
return user;
}
@Override
public Object getAllUserSettings(String userId) {
Query query = new Query();
query.addCriteria(Criteria.where("userId").is(userId));
User user = mongoTemplate.findOne(query, User.class);
return user != null ? user.getUserSettings() : "User not found.";
}
@Override
public String getUserSetting(String userId, String key) {
Query query = new Query();
query.fields().include("userSettings");
query.addCriteria(Criteria.where("userId").is(userId).andOperator(Criteria.where("userSettings." + key).exists(true)));
User user = mongoTemplate.findOne(query, User.class);
return user != null ? user.getUserSettings().get(key) : "Not found.";
}
@Override
public String addUserSetting(String userId, String key, String value) {
Query query = new Query();
query.addCriteria(Criteria.where("userId").is(userId));
User user = mongoTemplate.findOne(query, User.class);
if (user != null) {
user.getUserSettings().put(key, value);
mongoTemplate.save(user);
return "Key added.";
} else {
return "User not found.";
}
}
}
As implementações dos métodos na classe acima estão usando a dependência MongoTemplate. Veja como o método getUserById(...)
obtém o usuário. Construímos uma consulta e passamos os parâmetros necessários. O que vai te interessar mais é a consulta getUserSetting
. Vamos entender o que aconteceu acima:
- Construímos consultas com critérios para verificar igualdade.
- O método include inclui os nomes dos campos que o resultado deve incluir quando é extraído do banco de dados. Isso significa que, neste caso, a chave userSettings será extraída, o que economizará muitos dados a serem buscados, o que não é necessário
- Também consultamos tanto o usuário quanto a chave do mapa. Se algum deles não for encontrado, retornamos dados vazios, o que significa que a chave necessária não foi encontrada. Isso evita até mesmo buscar o objeto Usuário se a chave necessária não estiver presente
Execução de Teste do Spring Data MongoDB
Podemos executar este aplicativo simplesmente usando um único comando:
mvn spring-boot:run
Depois que o aplicativo estiver em execução, podemos tentar salvar um novo usuário usando esta API:
https://localhost:8102/user/create
Como esta será uma solicitação POST, também estaremos enviando dados JSON:
{
"name" : "Shubham",
"userSettings" : {
"bike" : "pulsar"
}
}
Como estamos retornando a própria resposta do Mongo, obteremos algo como:
{
"userId": "5a5f28cc3178058b0fafe1dd",
"name": "Shubham",
"creationDate": 1516165830856,
"userSettings": {
"bike" : "pulsar"
}
}
Você pode obter todos os usuários usando a API como solicitação GET:
https://localhost:8102/user/
Obteremos algo como:
[
{
"userId": "5a5f28cc3178058b0fafe1dd",
"name": "Shubham",
"creationDate": 1516165830856,
"userSettings": {
"bike" : "pulsar"
}
}
]
Se você observar a classe
UserController
acima, não conectamos o MongoTemplate para ser usado. O trecho de código abaixo mostra as alterações necessárias para usar o MongoTemplate para ler as configurações do usuário.
//definir objeto da Camada de Acesso a Dados
private final UserDAL userDAL;
//inicializar objeto DAL via injeção de dependência no construtor
public UserController(UserRepository userRepository, UserDAL userDAL) {
this.userRepository = userRepository;
this.userDAL = userDAL;
}
//alterar implementação do método para usar DAL e, portanto, MongoTemplate
@RequestMapping(value = "/settings/{userId}", method = RequestMethod.GET)
public Object getAllUserSettings(@PathVariable String userId) {
User user = userRepository.findOne(userId);
if (user != null) {
return userDAL.getAllUserSettings(userId);
} else {
return "User not found.";
}
}
//alterar implementação do método para usar DAL e, portanto, MongoTemplate
@RequestMapping(value = "/settings/{userId}/{key}", method = RequestMethod.GET)
public String getUserSetting(
@PathVariable String userId, @PathVariable String key) {
return userDAL.getUserSetting(userId, key);
}
Reinicie o aplicativo e execute cenários para obter todas as configurações do usuário e obter qualquer chave específica. A imagem abaixo mostra a saída do aplicativo Postman.
MongoTemplate vs MongoRepository
- O MongoTemplate oferece muito mais controle quando se trata de consultar dados e escolher quais dados buscar no banco de dados.
- Os repositórios do Spring Data nos proporcionam uma perspectiva conveniente de como buscar dados.
- O MongoTemplate depende do banco de dados. Isso significa que, com os repositórios do Spring Data, você pode facilmente mudar para um banco de dados diferente usando simplesmente repositórios do Spring Data diferentes para MySQL, Neo4J ou qualquer outro. Isso não é possível com o MongoTemplate.
Resumo do Spring Boot MongoDB
Nesta lição, examinamos como o MongoTemplate pode nos fornecer mais controle sobre os repositórios de dados do Spring, mas também pode ser um pouco complicado quando consultas mais profundas estão envolvidas. Então, essa é totalmente sua escolha sobre o que escolher ao desenvolver sua ideia. Sinta-se à vontade para deixar comentários abaixo. Baixe o código-fonte a partir do link abaixo. Certifique-se de alterar as credenciais do MongoDB antes de executar o aplicativo fornecido.
Source:
https://www.digitalocean.com/community/tutorials/spring-boot-mongodb