diff --git a/010_spring_boot/api_rest/api/src/main/java/med/voll/api/controller/MedicoController.java b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/controller/MedicoController.java index d24e904..76e6165 100644 --- a/010_spring_boot/api_rest/api/src/main/java/med/voll/api/controller/MedicoController.java +++ b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/controller/MedicoController.java @@ -1,18 +1,24 @@ package med.voll.api.controller; import jakarta.validation.Valid; +import med.voll.api.medico.DatosListadoMedicos; import med.voll.api.medico.DatosRegistroMedico; import med.voll.api.medico.Medico; import med.voll.api.medico.MedicoRepository; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.web.PageableDefault; import org.springframework.web.bind.annotation.*; +import java.util.List; + @RestController @RequestMapping("/medicos") public class MedicoController { - // No es recomendable usar @Autowired a nivel de declaración pues genera - // problemas al realizar pruebas unitarias + /* No es recomendable usar @Autowired a nivel de declaración pues genera + problemas al realizar pruebas unitarias */ @Autowired private MedicoRepository medicoRepository; @PostMapping @@ -20,4 +26,8 @@ public class MedicoController { medicoRepository.save(new Medico(datosRegistroMedico)); } + @GetMapping + public Page listadoMedicos(@PageableDefault(size = 5) Pageable paginacion) { + return medicoRepository.findAll(paginacion).map(DatosListadoMedicos::new); + } } diff --git a/010_spring_boot/api_rest/api/src/main/java/med/voll/api/controller/PacienteController.java b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/controller/PacienteController.java new file mode 100644 index 0000000..dd39d75 --- /dev/null +++ b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/controller/PacienteController.java @@ -0,0 +1,31 @@ +package med.voll.api.controller; + +import jakarta.validation.Valid; +import med.voll.api.paciente.DatosListadoPacientes; +import med.voll.api.paciente.DatosRegistroPaciente; +import med.voll.api.paciente.Paciente; +import med.voll.api.paciente.PacienteRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.web.PageableDefault; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/pacientes") +public class PacienteController { + + /* No es recomendable usar @Autowired a nivel de declaración pues genera + problemas al realizar pruebas unitarias */ + @Autowired + private PacienteRepository pacienteRepository; + @PostMapping + public void registrarPaciente(@RequestBody @Valid DatosRegistroPaciente datosRegistroPaciente) { + pacienteRepository.save(new Paciente(datosRegistroPaciente)); + } + + @GetMapping + public Page listadoPacientes(@PageableDefault(size = 5) Pageable paginacion) { + return pacienteRepository.findAll(paginacion).map(DatosListadoPacientes::new); + } +} diff --git a/010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/DatosListadoMedicos.java b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/DatosListadoMedicos.java new file mode 100644 index 0000000..60a3c89 --- /dev/null +++ b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/DatosListadoMedicos.java @@ -0,0 +1,12 @@ +package med.voll.api.medico; + +public record DatosListadoMedicos(String nombre, String especialidad, String documento, String email) { + + public DatosListadoMedicos (Medico medico) { + this(medico.getNombre(), + medico.getEspecialidad().toString(), + medico.getDocumento(), + medico.getEmail()); + } + +} \ No newline at end of file diff --git a/010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/Medico.java b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/Medico.java index 3df02fb..b7cfad3 100644 --- a/010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/Medico.java +++ b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/Medico.java @@ -22,7 +22,7 @@ public class Medico { private String email; private String telefono; private String documento; - @Enumerated + @Enumerated(EnumType.STRING) private Especialidad especialidad; @Embedded private Direccion direccion; @@ -30,8 +30,8 @@ public class Medico { public Medico(DatosRegistroMedico datosRegistroMedico) { this.nombre = datosRegistroMedico.nombre(); this.email = datosRegistroMedico.email(); - this.telefono = datosRegistroMedico.telefono(); this.documento = datosRegistroMedico.documento(); + this.telefono = datosRegistroMedico.telefono(); this.especialidad = datosRegistroMedico.especialidad(); this.direccion = new Direccion(datosRegistroMedico.direccion()); } diff --git a/010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/MedicoRepository.java b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/MedicoRepository.java index dfe4532..d667391 100644 --- a/010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/MedicoRepository.java +++ b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/medico/MedicoRepository.java @@ -2,4 +2,5 @@ package med.voll.api.medico; import org.springframework.data.jpa.repository.JpaRepository; -public interface MedicoRepository extends JpaRepository {} +public interface MedicoRepository extends JpaRepository { +} diff --git a/010_spring_boot/api_rest/api/src/main/java/med/voll/api/paciente/DatosListadoPacientes.java b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/paciente/DatosListadoPacientes.java new file mode 100644 index 0000000..cc29f2f --- /dev/null +++ b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/paciente/DatosListadoPacientes.java @@ -0,0 +1,11 @@ +package med.voll.api.paciente; + +public record DatosListadoPacientes(String nombre, String documento, String email) { + + public DatosListadoPacientes(Paciente medico) { + this(medico.getNombre(), + medico.getDocumento(), + medico.getEmail()); + } + +} \ No newline at end of file diff --git a/010_spring_boot/api_rest/api/src/main/java/med/voll/api/paciente/DatosRegistroPaciente.java b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/paciente/DatosRegistroPaciente.java new file mode 100644 index 0000000..4f7a9f2 --- /dev/null +++ b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/paciente/DatosRegistroPaciente.java @@ -0,0 +1,16 @@ +package med.voll.api.paciente; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import med.voll.api.direccion.DatosDireccion; + +public record DatosRegistroPaciente( + @NotBlank String nombre, + @NotBlank @Email String email, + @NotBlank String telefono, + @NotBlank @Pattern(regexp = "\\d{4,6}") String documento, + @NotNull @Valid DatosDireccion direccion +) {} diff --git a/010_spring_boot/api_rest/api/src/main/java/med/voll/api/paciente/Paciente.java b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/paciente/Paciente.java new file mode 100644 index 0000000..d7993f1 --- /dev/null +++ b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/paciente/Paciente.java @@ -0,0 +1,35 @@ +package med.voll.api.paciente; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import med.voll.api.direccion.Direccion; + +@Table(name="pacientes") +@Entity(name="Paciente") +@Getter +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(of = "id") +public class Paciente { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String nombre; + private String email; + private String telefono; + private String documento; + @Embedded + private Direccion direccion; + + public Paciente(DatosRegistroPaciente datosRegistroPaciente) { + this.nombre = datosRegistroPaciente.nombre(); + this.email = datosRegistroPaciente.email(); + this.documento = datosRegistroPaciente.documento(); + this.telefono = datosRegistroPaciente.telefono(); + this.direccion = new Direccion(datosRegistroPaciente.direccion()); + } +} diff --git a/010_spring_boot/api_rest/api/src/main/java/med/voll/api/paciente/PacienteRepository.java b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/paciente/PacienteRepository.java new file mode 100644 index 0000000..da767e7 --- /dev/null +++ b/010_spring_boot/api_rest/api/src/main/java/med/voll/api/paciente/PacienteRepository.java @@ -0,0 +1,6 @@ +package med.voll.api.paciente; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PacienteRepository extends JpaRepository { +} diff --git a/010_spring_boot/api_rest/api/src/main/resources/application.properties b/010_spring_boot/api_rest/api/src/main/resources/application.properties index 0794eec..8f27143 100644 --- a/010_spring_boot/api_rest/api/src/main/resources/application.properties +++ b/010_spring_boot/api_rest/api/src/main/resources/application.properties @@ -1,3 +1,6 @@ spring.datasource.url=jdbc:mysql://192.168.0.8/vollmed_api spring.datasource.username=alura -spring.datasource.password=alura \ No newline at end of file +spring.datasource.password=alura + +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.format_sql=true \ No newline at end of file diff --git a/010_spring_boot/api_rest/api/src/main/resources/db/migration/V3__create-table-pacientes.sql b/010_spring_boot/api_rest/api/src/main/resources/db/migration/V3__create-table-pacientes.sql new file mode 100644 index 0000000..540c256 --- /dev/null +++ b/010_spring_boot/api_rest/api/src/main/resources/db/migration/V3__create-table-pacientes.sql @@ -0,0 +1,16 @@ +create table pacientes( + + id bigint not null auto_increment, + nombre varchar(100) not null, + email varchar(100) not null unique, + documento varchar(6) not null unique, + telefono varchar(20) not null, + calle varchar(100) not null, + distrito varchar(100) not null, + complemento varchar(100), + numero varchar(20), + ciudad varchar(100) not null, + + primary key(id) + +); \ No newline at end of file diff --git a/010_spring_boot/populate_vollmed_db/populate_medicos.sql b/010_spring_boot/populate_vollmed_db/populate_medicos.sql new file mode 100644 index 0000000..3c20543 --- /dev/null +++ b/010_spring_boot/populate_vollmed_db/populate_medicos.sql @@ -0,0 +1,20 @@ +USE vollmed_api; +INSERT INTO vollmed_api.medicos(nombre, email, telefono, documento, especialidad, calle, distrito, complemento, ciudad, numero) + VALUES + ('Cuarto Medico', 'dr_4@voll.med', '44444', '444444', 'CARDIOLOGIA', 'calle 4', 'distrito 4', 'prueba', 'Santiago', '4'), + ('Quinto Medico', 'dr_5@voll.med', '55555', '555555', 'PEDIATRIA', 'calle 5', 'distrito 5', 'prueba', 'Santiago', '5'), + ('Sexto Medico', 'dr_6@voll.med', '66666', '666666', 'ORTOPEDIA', 'calle 6', 'distrito 6', 'prueba', 'Santiago', '6'), + ('Septimo Medico', 'dr_7@voll.med', '77777', '777777', 'GINECOLOGIA', 'calle 7', 'distrito 7', 'prueba', 'Santiago', '7'), + ('Octavo Medico', 'dr_8@voll.med', '88888', '888888', 'CARDIOLOGIA', 'calle 8', 'distrito 8', 'prueba', 'Santiago', '8'), + ('Noveno Medico', 'dr_9@voll.med', '99999', '999999', 'PEDIATRIA', 'calle 9', 'distrito 9', 'prueba', 'Santiago', '9'), + ('Decimo Medico', 'dr_10@voll.med', '10101', '101010', 'ORTOPEDIA', 'calle 10', 'distrito 10', 'prueba', 'Santiago', '10'), + ('Onceavo Medico', 'dr_11@voll.med', '11011', '110111', 'CARDIOLOGIA', 'calle 11', 'distrito 11', 'prueba', 'Santiago', '11'), + ('Doceavo Medico', 'dr_12@voll.med', '12121', '121212', 'PEDIATRIA', 'calle 12', 'distrito 12', 'prueba', 'Santiago', '12'), + ('Treceavo Medico', 'dr_13@voll.med', '13131', '131313', 'ORTOPEDIA', 'calle 13', 'distrito 13', 'prueba', 'Santiago', '13'), + ('Catorceavo Medico', 'dr_14@voll.med', '14141', '141414', 'GINECOLOGIA', 'calle 14', 'distrito 14', 'prueba', 'Santiago', '14'), + ('Quinceavo Medico', 'dr_15@voll.med', '15151', '151515', 'CARDIOLOGIA', 'calle 15', 'distrito 15', 'prueba', 'Santiago', '15'), + ('Diesiceisavo Medico', 'dr_16@voll.med', '16161', '161616', 'PEDIATRIA', 'calle 16', 'distrito 16', 'prueba', 'Santiago', '16'), + ('Diesicieteavo Medico', 'dr_17@voll.med', '17171', '171717', 'ORTOPEDIA', 'calle 17', 'distrito 17', 'prueba', 'Santiago', '17'), + ('Diesiochoavo Medico', 'dr_18@voll.med', '18181', '181818', 'GINECOLOGIA', 'calle 18', 'distrito 18', 'prueba', 'Santiago', '18'), + ('Diecinueveavo Medico', 'dr_19@voll.med', '19191', '191919', 'CARDIOLOGIA', 'calle 19', 'distrito 19', 'prueba', 'Santiago', '19'), + ('Veinteavo Medico', 'dr_20@voll.med', '20202', '202020', 'PEDIATRIA', 'calle 20', 'distrito 20', 'prueba', 'Santiago', '20'); diff --git a/010_spring_boot/populate_vollmed_db/populate_pacientes.sql b/010_spring_boot/populate_vollmed_db/populate_pacientes.sql new file mode 100644 index 0000000..d0e6c85 --- /dev/null +++ b/010_spring_boot/populate_vollmed_db/populate_pacientes.sql @@ -0,0 +1,20 @@ +USE vollmed_api; +INSERT INTO vollmed_api.pacientes(nombre, email, telefono, documento, calle, distrito, complemento, ciudad, numero) + VALUES + ('Cuarto Paciente', 'paciente_4@private.cl', '44444', '444444', 'calle 4', 'distrito 4', 'prueba', 'Santiago', '4'), + ('Quinto Paciente', 'paciente_5@private.cl', '55555', '555555', 'calle 5', 'distrito 5', 'prueba', 'Santiago', '5'), + ('Sexto Paciente', 'paciente_6@private.cl', '66666', '666666', 'calle 6', 'distrito 6', 'prueba', 'Santiago', '6'), + ('Septimo Paciente', 'paciente_7@private.cl', '77777', '777777', 'calle 7', 'distrito 7', 'prueba', 'Santiago', '7'), + ('Octavo Paciente', 'paciente_8@private.cl', '88888', '888888', 'calle 8', 'distrito 8', 'prueba', 'Santiago', '8'), + ('Noveno Paciente', 'paciente_9@private.cl', '99999', '999999', 'calle 9', 'distrito 9', 'prueba', 'Santiago', '9'), + ('Decimo Paciente', 'paciente_10@private.cl', '10101', '101010', 'calle 10', 'distrito 10', 'prueba', 'Santiago', '10'), + ('Onceavo Paciente', 'paciente_11@private.cl', '11011', '110111', 'calle 11', 'distrito 11', 'prueba', 'Santiago', '11'), + ('Doceavo Paciente', 'paciente_12@private.cl', '12121', '121212', 'calle 12', 'distrito 12', 'prueba', 'Santiago', '12'), + ('Treceavo Paciente', 'paciente_13@private.cl', '13131', '131313', 'calle 13', 'distrito 13', 'prueba', 'Santiago', '13'), + ('Catorceavo Paciente', 'paciente_14@private.cl', '14141', '141414', 'calle 14', 'distrito 14', 'prueba', 'Santiago', '14'), + ('Quinceavo Paciente', 'paciente_15@private.cl', '15151', '151515', 'calle 15', 'distrito 15', 'prueba', 'Santiago', '15'), + ('Diesiceisavo Paciente', 'paciente_16@private.cl', '16161', '161616', 'calle 16', 'distrito 16', 'prueba', 'Santiago', '16'), + ('Diesicieteavo Paciente', 'paciente_17@private.cl', '17171', '171717', 'calle 17', 'distrito 17', 'prueba', 'Santiago', '17'), + ('Diesiochoavo Paciente', 'paciente_18@private.cl', '18181', '181818', 'calle 18', 'distrito 18', 'prueba', 'Santiago', '18'), + ('Diecinueveavo Paciente', 'paciente_19@private.cl', '19191', '191919', 'calle 19', 'distrito 19', 'prueba', 'Santiago', '19'), + ('Veinteavo Paciente', 'paciente_20@private.cl', '20202', '202020', 'calle 20', 'distrito 20', 'prueba', 'Santiago', '20'); diff --git a/010_spring_boot/spring_boot_1.md b/010_spring_boot/spring_boot_1.md index a32dde5..3d905b8 100644 --- a/010_spring_boot/spring_boot_1.md +++ b/010_spring_boot/spring_boot_1.md @@ -330,7 +330,8 @@ Documentación Java ## Agregando dependencias -Copiar `xml` de Spring [initializr](https://start.spring.io/), y pegar en `pom.xml` +Copiar sección del `xml` de Spring [initializr](https://start.spring.io/), y +pegar en `pom.xml` Modificar `resources/application.properties` @@ -413,10 +414,11 @@ public class ProductoDao { En el ejemplo anterior, se utilizó JPA como tecnología de persistencia de datos de la aplicación. -**Patrón Repository**. Según el famoso libro Domain-Driven Design de Eric Evans: +**Patrón Repository** según el famoso libro *Domain-Driven Design* de *Eric +Evans*: -El repositorio es un mecanismo para encapsular el almacenamiento, recuperación y -comportamiento de búsqueda, que emula una colección de objetos. +> *El repositorio es un mecanismo para encapsular el almacenamiento, recuperación y +comportamiento de búsqueda, que emula una colección de objetos.* En pocas palabras, un repositorio también maneja datos y oculta consultas similares a DAO. Sin embargo, se encuentra en un nivel más alto, más cerca de @@ -516,3 +518,206 @@ estableciendo una colaboración entre componentes. Para más información sobre la anotación, ver la [documentación oficial](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Autowired.html) +## Get + +### Consideraciones + +Información requerida del médico + +- Nombre +- Especialidad +- Documento +- Email + +Reglas del negocio + +- Orden ascendente +- Paginado, máximo 10 registros por página + +
+ +En +[MedicoController](./api_rest/api/src/main/java/med/voll/api/controller/MedicoController.java) +se utilizo DTO para representar los datos recibi4os y devueltos a través de la +API, *¿Por qué, en lugar de crear un DTO, no devolvemos directamente la entidad +JPA en el Controller?*. Para esto, basta con cambiar método `listadoMedicos()` +en el Controller a: + +```java +@GetMapping +public List listarMedicos() { + return repository.findAll(); +} +``` + +De esa forma, el código sería más ligero y no necesitaríamos crear el DTO +en el proyecto. Pero, **¿es esto realmente una buena idea?** + +#### Problemas de recepción/devolución de la entidad JPA + +De hecho, es mucho más simple y cómodo no usar DTO, sino tratar directamente +con entidades JPA en los Controllers. Sin embargo, este enfoque tiene algunas +desventajas, incluida la vulnerabilidad de la aplicación a los ataques de +*Mass Assignment*. + +Uno de los problemas, es que al devolver una entidad JPA en un método del +Controller, Spring generará el JSON que contiene todos sus atributos, y este no +siempre es el comportamiento deseado. + +Eventualmente pueden tener atributos que no se requiere que sean devueltos en el +JSON, ya sea por razones de seguridad, en el caso de datos sensibles, o incluso +porque no son utilizados por clientes API. + +#### Uso de la anotación `@JsonIgnore` + +En esta situación, se puede usar la anotación `@JsonIgnore`, que nos ayuda a +ignorar ciertas propiedades de una clase Java cuando se serializa en un objeto +JSON. + +Su uso consiste en agregar la anotación a los atributos que se quieren ignorar +cuando se genera el JSON. Por ejemplo, supongamos que tenemos una entidad JPA +`Empleado`, en la que se quiere ignorar el atributo `salario`: + +```java +@Getter +@NoArgsConstructor +@EqualsAndHashCode(of = "id") +@Entity(name = "Empleado") +@Table(name = "empleados") +public class Empleado { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String nombre; + private String email; + + @JsonIgnore + private BigDecimal salario; + ... +} +``` + +En el ejemplo anterior, el atributo `salario` de la clase `Empleado` no será +mostrado en las respuestas JSON y el problema estaría resuelto. + +Sin embargo, puede haber algún otro endpoint de la API en el que necesitemos +enviar el salario de los empleados en el JSON, en cuyo caso se tendrían problemas, +ya que con la anotación `@JsonIgnore` tal atributo nunca se enviará en el JSON, +y al eliminar la anotación se enviará el atributo siempre. Por lo tanto, +se pierde la flexibilidad de controlar cuándo se deben enviar ciertos atributos +en el JSON y cuándo no. + +#### DTO + +El patrón **DTO** (***Data Transfer Object***) es un patrón arquitectónico que +se usó ampliamente en aplicaciones Java distribuidas (arquitectura +cliente/servidor) para representar los datos que eran enviados y recibidos entre +aplicaciones cliente y servidor. + +El patrón **DTO** puede (y debe) usarse cuando no queremos exponer todos los +atributos de alguna entidad en nuestro proyecto, una situación similar a los +salarios de los empleados que discutimos anteriormente. Además, con la +flexibilidad y la opción de filtrar qué datos se transmiten, podemos ahorrar +tiempo de procesamiento. + +#### Bucle infinito que causa StackOverflowError + +Otro problema muy recurrente cuando se trabaja directamente con entidades JPA +ocurre cuando una entidad tiene alguna *auto-relación* o *relación +bidireccional*. Por ejemplo, considere las siguientes entidades JPA: + +```java +@Getter +@NoArgsConstructor +@EqualsAndHashCode(of = "id") +@Entity(name = "Producto") +@Table(name = "productos") +public class Producto { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String nombre; + private String descripcion; + private BigDecimal precio; + + @ManyToOne + @JoinColumn(name = “id_categoria”) + private Categoria categoria; + + ... +} +``` + +```java +@Getter +@NoArgsConstructor +@EqualsAndHashCode(of = "id") +@Entity(name = "Categoria") +@Table(name = "categorias") +public class Categoria { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String nombre; + + @OneToMany(mappedBy = “categoria”) + private List productos = new ArrayList<>(); + + ... +} +``` + +Al devolver un objeto de tipo `Producto` en el Controller, Spring tendría +problemas para generar el JSON de este objeto, lo que provocaría una excepción +de tipo `StackOverflowError`. Este problema ocurre porque el objeto producto +tiene un atributo de tipo `Categoria`, que a su vez tiene un atributo de tipo +`Lista` lo que provoca un bucle infinito en el proceso de serialización +a JSON. + +Este problema se puede resolver usando la anotación `@JsonIgnore` o usando las +anotaciones `@JsonBackReference` y `@JsonManagedReference`, pero también se puede +evitar usando un DTO que represente solo los datos que se deben devolver en el +JSON. + +### Paginación y Orden + +Para la paginación se utiliza la interfase `Pageable` + +```java + ... + @GetMapping + public Page listadoMedicos( + @PageableDefault(size = 5) Pageable paginacion + ) { + return medicoRepository.findAll(paginacion).map(DatosListadoMedicos::new); + } +} +``` + +Estos pueden pre-establecerse con la anotación `@PageableDefault`, o en el archivo +[application.properties](./api_rest/api/src/main/resources/application.properties) + +```ini +spring.data.web.pageable.page-parameter=0 +spring.data.web.pageable.size-parameter=5 +spring.data.web.sort.sort-parameter=nombre +``` + +Estos además pueden ser sobrescritos al hacer el request: + +```http +http://127.0.0.1:8080/medicos?size=3&page=2&sort=documento,desc +``` + +#### Ver y formatear querys en el IDE + +En archivo [application.properties](./api_rest/api/src/main/resources/application.properties) + +```ini +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.format_sql=true +``` +