CRUD con Spring Boot + JPA + PostgreSQL + Pagination + Validator + Swagger
En este post les mostrare como realizar un CRUD en Spring Boot, usaremos una base de datos relacional de PostgreSQL, la cual correremos en local.
Anteriormente ya habia realizado un CRUD en Spring Boot, pero este es una version mejorada del anterior.
Sobre los temas que abordaremos en este proyecto seran:
- JPA
- Pagination o paginacion: nos permite paginar nuestros resultados de base de datos.
- Validators: validadores en Spring Boot, los permiten validar campos vacios o nulos de una entidad o modelo de datos.
- PostgreSQL: la base de datos open source mas popular.
- Gradle: con gradle podremos administrar dependencias y contruccion de nuestros poyectos de manera mas rapida.
- Java 17
- Spring Boot 2.5.6
- Lombok
- Swagger
Estructura del proyecto
Este sera un proyecto sencillo con las operaciones basicas de CRUD. Veamos la estructura general del proyecto.
Controller
Controlador rest que administra o recibe las peticiones HTTP.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import xyz.yoandroide.crud.model.Student;
import xyz.yoandroide.crud.service.StudentService;
import javax.validation.Valid;
import java.util.Optional;
@RestController
@RequestMapping("/student")
public class StudentController {
@Autowired
private StudentService studentService;
@PostMapping
public ResponseEntity<Student> saveStudent (@Valid @RequestBody Student student){
return ResponseEntity.status(HttpStatus.CREATED).body(studentService.saveStudent(student));
}
@GetMapping
public ResponseEntity<Page<Student>> getAllStudent (
@RequestParam(required = false, defaultValue = "0") Integer page,
@RequestParam(required = false, defaultValue = "10") Integer size,
@RequestParam(required = false, defaultValue = "false") Boolean enablePagination
){
return ResponseEntity.ok(studentService.getAllStudent(page, size, enablePagination));
}
@DeleteMapping(value = "/{id}")
public ResponseEntity deleteStudent(@PathVariable ("id") Long id){
studentService.deleteStudent(id);
return ResponseEntity.ok(!studentService.existById(id));
}
@GetMapping(value = "/{id}")
public ResponseEntity<Optional<Student>> findStudentById(@PathVariable ("id") Long id){
return ResponseEntity.status(HttpStatus.OK).body(studentService.findById(id));
}
@PutMapping
public ResponseEntity<Student> editStudent (@Valid @RequestBody Student student){
return ResponseEntity.status(HttpStatus.CREATED).body(studentService.editStudent(student));
}
}
Model
Es el pequete donde se guardan los modelos de los objetos u entidades.
import lombok.Data;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
@Data
@Entity
@Table(name = "Student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotBlank
private String name;
@NotBlank
private String lastName;
private Integer age;
}
Repository
Interfaces con la conexion al repositorio de JPA.
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import xyz.yoandroide.crud.model.Student;
@Repository
public interface IStudentRepository extends JpaRepository<Student, Long> {
}
Service
Logica del negocio.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import xyz.yoandroide.crud.model.Student;
import xyz.yoandroide.crud.repository.IStudentRepository;
import java.util.Optional;
@Service
public class StudentService {
@Autowired
private IStudentRepository iStudentRepository;
public Student saveStudent (Student student){
if (student.getId() == null){
return iStudentRepository.save(student);
}
return null;
}
public Page<Student> getAllStudent (Integer page, Integer size, Boolean enablePagination){
return iStudentRepository.findAll(enablePagination ? PageRequest.of(page, size): Pageable.unpaged());
}
public Optional<Student> findById(Long id){
return iStudentRepository.findById(id);
}
public void deleteStudent(Long id){
iStudentRepository.deleteById(id);
}
public Student editStudent (Student student){
if (student.getId() != null && iStudentRepository.existsById(student.getId())){
return iStudentRepository.save(student);
}
return null;
}
public boolean existById(Long id) {
return iStudentRepository.existsById(id);
}
}
Dependencias
Este es un proyecto gradle, asi que aqui te dejo las dependencias y configuracion usada.
plugins {
id 'org.springframework.boot' version '2.5.6'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'xyz.yoandroide'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
runtimeOnly 'org.postgresql:postgresql'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.boot:spring-boot-starter-validation:2.5.6'
compileOnly 'org.projectlombok:lombok:1.18.22'
annotationProcessor 'org.projectlombok:lombok:1.18.22'
testCompileOnly 'org.projectlombok:lombok:1.18.22'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.22'
// https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-ui
implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.5.12'
}
test {
useJUnitPlatform()
}
Archivo properties
Esta es la configuracion para acceder a la base de datos. Cabe resaltar que debes tener creada una base de datos en PostgreSQL en local para que el proyecto funcione.
Este es el arcivo application.properties
spring.jpa.database=POSTGRESQL
spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://localhost:5432/crud
spring.datasource.username=postgres
spring.datasource.password=password
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
Nota: no olvides comentar la linea spring.jpa.generate-ddl=true y spring.jpa.hibernate.ddl-auto=create-drop una vez que se haya construido la base de datos, de lo contrario, se te eliminara la base de datos cada que vuelvas a correr el proecto.
Video-tutorial
Aqui te dejo un video-tutorial explicando paso a paso como fue que se construyo este CRUD. El video esta alojado en el canal de Youtube Yo Androide.
- Cómo Dockerizar una Aplicación Spring Boot con Kotlin: Guía Paso a PasoDockerizar tu backend, microservicio o aplicación en Spring Boot y con lenguaje…
- Java + Spring Boot Semi Senior: Lo que deberías saberHace un tiempo grabé un video sobre lo que deberías saber para…
- Agregar Actuator + Grafana + Prometheus a Spring BootEn este post veremos como configurar Actuator, Prometheus y Grafana para moitorear…
- CRUD con Spring Boot + JPA + PostgreSQL + Pagination + Validator + SwaggerEn este post les mostrare como realizar un CRUD en Spring Boot,…
- Lombok y Spring Boot: Agregar y configurar desde ceroEn este post te enseñare como agregar y configurar Lombok en un…
Si quieres conocer otros artículos parecidos a CRUD con Spring Boot + JPA + PostgreSQL + Pagination + Validator + Swagger puedes visitar la categoría Java.
Entradas relacionadas