Datos de primavera: tutorial de MongoDB

Spring Data es un proyecto general que contiene muchos submódulos, cada uno específico para una base de datos en particular. En este artículo, cubriremos Spring Data Mongo...

Visión general

Datos de primavera es un proyecto paraguas que contiene muchos submódulos, cada uno específico para una base de datos en particular. En este artículo, cubriremos Datos de primavera MongoDB construyendo una aplicación que almacena y recupera datos de MongoDB, un documento basado en NO- Base de datos SQL.

Si desea leer más sobre Spring Data, lo hemos cubierto en detalle en - Guía de Spring Data JPA.

Mongo DB

MongoDB es una base de datos NoSQL orientada a documentos que almacena documentos similares a JSON con esquemas dinámicos. Se utiliza comúnmente para el almacenamiento de datos de gran volumen.

Antes de seguir adelante, sería bueno conocer algunos de los términos de la base de datos NoSQL. Tenga en cuenta que estos términos no son exactamente uno a uno en comparación con las bases de datos SQL relacionales:

  • Base de datos: es un contenedor de colecciones y se puede considerar similar a una base de datos RDBMS, que es un contenedor de tablas.
  • Colección: Es equivalente a Tablas en RDBMS, pero a diferencia de una colección tiene un esquema dinámico. Una colección existe dentro de una base de datos.
  • Documento: Es un único registro en una colección MongoDB. Se puede considerar como una fila en RDBMS.
  • Campo: Un documento tiene cero o más campos. Es como una columna RDBMS que tiene un par clave-valor.

Para configurar el servidor MongoDB en su máquina local, puede descargar el instalable aquí según su sistema operativo. Luego, también puede descargar una herramienta como Brújula para que una GUI agradable interactúe con su servidor.

Otra opción y la que usaremos es Mongo DB Atlas, que es una base de datos en la nube como servicio. Después de registrarse, inicie sesión y cree un clúster con el nivel gratuito:

MongoDB Atlas create cluster

Descripción general del clúster de MongoDB Atlas

Para conectarnos a nuestro clúster, tenemos que crear un usuario:

MongoDB Atlas create user

Ahora vamos a crear nuestra base de datos y colección:

Crear base de datos MongoDB

Ahora estamos listos para conectarnos a nuestra colección usando nuestra aplicación Spring.

Proyecto Spring Data MongoDB

Configuración

La mejor manera de comenzar con un proyecto básico es visitar Spring Initializr. Seleccione su versión preferida de Spring Boot y agregue las dependencias Web y MongoDB:

Inicializar primavera

Después de esto, genere como un proyecto Maven y ¡ya está todo listo!

Definición de una colección {#definición de una colección}

Primero, definamos nuestra clase de modelo de colección Candidate:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
@Document(collection = "candidate")
public class Candidate {
    @Id
    private String id;

    private String name;

    private double exp;

    @Indexed(unique = true)
    private String email;

    // getters and setters
}

Ahora echemos un vistazo a estas anotaciones:

  • @Documento: Esto marca la clase como un objeto de dominio que persistirá en la base de datos. El nombre de colección predeterminado que se utiliza es el nombre de la clase (primer carácter en minúsculas). Podemos mapear a una colección diferente en la base de datos usando el atributo colección de la anotación.
  • @Id: Esto marca el campo utilizado con fines de identidad.
  • @Indexed(unique = true): Esto se aplica al campo que será indexado con una restricción de único.

Definición de repositorio

Creamos un repositorio haciendo una interfaz:

1
public interface CandidateRepository extends MongoRepository<Candidate, String> {}

CandidateRepository amplía la interfaz de MongoRepository y conecta el tipo de datos del documento con el que estamos trabajando, es decir, Candidate y String respectivamente.

Esto nos dará acceso a todas las operaciones CRUD alrededor de la colección MongoDB.

Configuración de conexión {#configuración de conexión}

Para configurar una conexión adecuada, necesitamos definir las propiedades de conexión en application.properties:

1
spring.data.mongodb.uri=mongodb+srv://<USERNAME>:<PASSWORD>@<ClUSTER-NAME>-<INSTANCE-ID>/<DATABASE-NAME>?retryWrites=true

Puede obtener estos valores directamente desde la interfaz de usuario de MongoDB Atlas:

URL de conexión de Atlas

Nota: si su contraseña contiene caracteres especiales, debe estar codificada como URL.

De forma predeterminada, su clúster está protegido para no recibir solicitudes de ninguna IP de cliente. Necesitamos permitir que nuestra IP pueda conectarse a este clúster a través de una lista blanca de IP:

Lista blanca de IP de Atlas 1

Lista blanca de IP de Atlas 2

Definición del controlador

Ahora, usemos nuestro repositorio en nuestro CandidateController a través de la anotación @Autowired:

1
2
3
4
5
6
@RestController
@RequestMapping("/candidate")
public class CandidateController {

    @Autowired
    private CandidateRepository candidateRepository;

Operaciones CRUD simples

Insertar

Vamos a crear un mapeo POST que insertará datos en nuestro MongoDB:

1
2
3
4
5
@PostMapping
@ResponseStatus(code = HttpStatus.CREATED)
public Candidate add(@RequestBody Candidate candidate) {
    return candidateRepository.save(candidate);
}

Usamos el método save() en el objeto candidateRepository. El objeto Candidate es capturado por @RequestBody y se usa directamente en el método save().

MongoDB insert 1

Si intentamos usar la misma ID de correo electrónico nuevamente, obtendremos un error de clave duplicada:

MongoDB insert 2

También podemos comprobar el estado de nuestra colección en Atlas:

MongoDB insert 3

Leer

Vamos a crear un par de asignaciones GET para obtener nuestros registros.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@GetMapping
public List<Candidate> getAll() {
    return candidateRepository.findAll();
}

@GetMapping(value = "/{id}")
public Candidate getOne(@PathVariable String id) {
    return candidateRepository.findById(id)
        .orElseThrow(() -> new ResourceNotFoundException());
}

findAll() devolverá todos los registros en nuestra base de datos, mientras que el método findById() devolverá un solo registro basado en la ID pasada.

MongoDB insert

Si el registro no está presente, “arroja” una excepción de tiempo de ejecución personalizada. ResourceNotFoundException es una clase personalizada que devuelve el estado 404 si se lanza:

1
2
3
4
5
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException() {
    }
}

Si desea leer más sobre esto, lo cubrimos en detalle en - Manejo de excepciones en Spring.

Actualizar

Ahora, para actualizar un registro en particular, usaremos un mapeo PUT:

1
2
3
4
5
6
7
8
9
@PutMapping(value = "/{id}")
public Candidate update(@PathVariable String id, @RequestBody Candidate updatedCandidate) {
    Candidate candidate = candidateRepository.findById(id)
        .orElseThrow(() -> new ResourceNotFoundException());
    candidate.setName(updatedCandidate.getName());
    candidate.setExp(updatedCandidate.getExp());
    candidate.setEmail(updatedCandidate.getEmail());
    return candidateRepository.save(candidate);
}

Primero verificamos si el ‘Candidato’ con el ‘id’ dado está presente o no. Si no, devolvemos un estado 404, de lo contrario, actualizamos todo el objeto y lo guardamos usando el método save():

Actualización de MongoDB

Borrar

Ahora, eliminemos un registro en particular usando el mapeo DELETE:

1
2
3
4
5
6
7
@DeleteMapping(value = "/{id}")
@ResponseStatus(code = HttpStatus.ACCEPTED)
public void delete(@PathVariable String id) {
    Candidate candidate = candidateRepository.findById(id)
        .orElseThrow(() -> new ResourceNotFoundException());
    candidateRepository.delete(candidate);
}

Usamos el método delete() en candidateRepository para eliminar la entrada:

MongoDB delete

Métodos de consulta personalizados

Podemos agregar algunos métodos a nuestro CandidateRepository para tener alguna funcionalidad adicional basada en nuestros requisitos comerciales:

1
2
3
4
5
6
7
8
public interface CandidateRepository extends MongoRepository<Candidate, String> {

    Optional<Candidate> findByEmail(String email);

    List<Candidate> findByExpGreaterThanEqual(double exp);

    List<Candidate> findByExpBetween(double from, double to);
}

Arriba, agregamos la funcionalidad de búsqueda basada en el correo electrónico y la experiencia. Todo lo que tenemos que hacer es seguir una convención de nomenclatura establecida por Datos de primavera.

Después del método findBy() escribimos el nombre del atributo en mayúsculas y minúsculas, seguido de cualquier otra restricción que queramos aplicar. Los argumentos del método deben coincidir con la expectativa de la cláusula where. Spring Data creará consultas reales para usted durante el inicio de la aplicación mediante el uso de esta interfaz.

Usemos esto en nuestro controlador:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
@GetMapping("/searchByEmail")
public Candidate searchByEmail(@RequestParam(name = "email") String email) {
    return candidateRepository.findByEmail(email)
        .orElseThrow(() -> new ResourceNotFoundException());

}

@GetMapping("/searchByExp")
public List<Candidate> searchByExp(@RequestParam(name = "expFrom") Double expFrom, @RequestParam(name = "expTo", required = false) Double expTo) {
    List<Candidate> result = new ArrayList<>();
    if (expTo != null) {
        result = candidateRepository.findByExpBetween(expFrom, expTo);
    } else {
        result = candidateRepository.findByExpGreaterThanEqual(expFrom);
    }
    return result;
}

Consultas personalizadas de MongoDB

Conclusión

En este artículo, hemos cubierto cómo usar Spring Data MongoDB para conectarse a un servidor MongoDB. Primero creamos un servidor MongoDB en la nube usando MongoDB Atlas y luego usamos Spring Data para conectarnos a él. Después de eso, realizamos una operación CRUD simple y escribimos algunas consultas personalizadas.

Como siempre, el código de los ejemplos utilizados en este artículo se puede encontrar en Github.