Saltar navegación

20260210 API_REST_1 - Contenido educativo

Ajuste de pantalla

El ajuste de pantalla se aprecia al ver el vídeo en pantalla completa. Elige la presentación que más te guste:

Subido el 10 de febrero de 2026 por Raquel G.

1 visualizaciones

Descargar la transcripción

Vamos, bueno, pues sabemos JPA, ¿vale? 00:00:00
Sabemos que es un contexto de persistencia, el Entity Manager. 00:00:04
Sabemos los métodos que ofrece el Entity Manager para hacer la persistencia, 00:00:07
como Save, como Get por clave primaria. 00:00:13
Y sabemos construir una aplicación que trabaje con objetos persistentes 00:00:16
directamente con el JPA puro, con el Entity Manager, ¿vale? 00:00:20
Y ya está, ¿vale? 00:00:24
¿Qué más sabemos? 00:00:25
pues para envolver la complejidad 00:00:26
del entity manager y de las transacciones 00:00:29
y sobre todo 00:00:31
por la facilidad adicional 00:00:35
de generarnos código automáticamente 00:00:37
pues tenemos la capa 00:00:39
por encima de sprint 00:00:41
la capa por encima de sprint 00:00:42
ya sabemos que me permite 00:00:44
haciendo interfaz 00:00:47
de repositorio que esas interfaces 00:00:50
se rellenen automáticamente 00:00:53
Simplemente a través del nombre 00:00:55
Del método 00:00:58
Aparte de los que me ofrece 00:00:59
Que yo quiero además 00:01:01
Alguna cosa 00:01:04
Que no pueda hacer a través del nombre 00:01:06
Del método 00:01:08
O diferente a las que me ofrece 00:01:08
Plantamos una query y ya está 00:01:11
Entonces Spring JPA nos ofrece 00:01:13
Esos repositorios 00:01:15
Que concluimos crear una especie de 00:01:16
Capa que tapa 00:01:19
Al DAO nuestro puro y duro 00:01:21
Entonces el repository se hace su DAO 00:01:23
Por debajo y nos ofrece métodos 00:01:26
Un poquito más elaborados 00:01:28
Que los del DAO, el CRUD puro y duro del DAO 00:01:30
Entonces al repository ya lo llamamos 00:01:32
Del servicio y se acabó 00:01:34
Y que más nos ofrece Spring 00:01:36
La gestión de los bins 00:01:37
La autoinyección de las cosas que sean necesarias 00:01:39
De dos maneras 00:01:42
De dos maneras 00:01:44
Sin Spring Boot 00:01:47
O con Spring Boot 00:01:48
Sin Spring Boot tenemos que configurar los bins 00:01:50
a mano, bien con 00:01:53
anotaciones en la clase, tipo 00:01:55
service, repository no hace falta porque se infiera 00:01:57
automáticamente si heredas de jpa 00:01:59
repository, o bien en la clase 00:02:01
de configuración, donde vas poniendo bin, bin, bin 00:02:03
y los tienes que configurar a mano 00:02:05
que en una aplicación jpa 00:02:07
¿cuáles son los imprescindibles? 00:02:09
el entity manager factory 00:02:12
porque es el que saca el entity manager 00:02:13
pues hay que ponerlo en el app.conf como se instancia 00:02:15
el data source, porque el entity manager 00:02:17
se engancha a un data source, pues hay que poner 00:02:19
el app.config como su instancia 00:02:21
y si gestionas transacciones 00:02:23
que siempre gestionamos 00:02:25
transacciones, pues 00:02:27
el transaction manager 00:02:29
eran esos tres bins, aparte de los 00:02:31
service y los repositorios 00:02:33
esos los maneja Spring solo 00:02:34
¿que no queremos configurarlos con 00:02:37
nuestra clase 00:02:39
de configuración? Pues Spring Boot 00:02:41
Spring Boot los configura 00:02:43
automáticamente 00:02:45
a partir de un fichero properties 00:02:46
¿vale? Entonces, con 00:02:49
esa arquitectura ya montada, pues uno 00:02:51
llama al servicio y hace lo que le dé 00:02:53
la gana, que a su vez tirar al repositorio, etc. 00:02:55
Siempre 00:02:59
apoyado, por supuesto, en 00:02:59
una buena declaración del modelo 00:03:01
con las anotaciones correctas y todo eso. 00:03:03
Eso es en resumen 00:03:06
lo que hemos visto. 00:03:07
¿Vale? En resumen lo que hemos visto. 00:03:09
Luego ya, claro, 00:03:12
cada caso en particular 00:03:13
o cada modelo en particular, pues tiene 00:03:14
sus peculiaridades. 00:03:17
Bueno, pues 00:03:19
Dijimos que íbamos a hacer lo mismo, pero cambiado a, ahora ya no hacer las pruebas con un main, porque bueno, eso es un poco chapuzo, hacer un servicio, hacer toda esa arquitectura, pero luego llamarlo desde un main, una aplicación de escritorio, pero bueno, como para pruebas de que la arquitectura funcionaba, sobraba. 00:03:20
Pues ahora en lugar 00:03:42
Desde un main 00:03:46
Vamos a probarlo 00:03:47
Desde 00:03:50
Una arquitectura 00:03:52
Con el modelo 00:03:54
MVC, modelo vista controlador 00:03:56
¿Vale? ¿Por qué? Porque 00:03:58
Podemos hacer nosotros 00:04:00
Esto 00:04:02
Una arquitectura modelo vista controlador 00:04:04
Nosotros a mano directamente 00:04:06
Y ya sabéis como 00:04:08
Lo sabéis desde hace dos meses o tres meses 00:04:09
Haciendo yo 00:04:12
el servlet, es decir 00:04:13
el servlet que responde a cada 00:04:15
URL que a mí me dé la gana 00:04:18
al fin y al cabo que es una 00:04:19
aplicación construida 00:04:21
en un servidor web, alguien que 00:04:24
responde a URLs, a 00:04:26
peticiones HTTP, eso es una 00:04:27
aplicación montada en un servidor de aplicaciones 00:04:29
alguien que está ahí a la escucha de peticiones 00:04:31
HTTP, bueno 00:04:34
pues podemos hacer nosotros a mano 00:04:35
un servlet para cada petición 00:04:37
HTTP y dentro de ese servlet 00:04:40
llamamos a nuestro servicio 00:04:41
Y construimos la respuesta 00:04:42
La construimos 00:04:45
Y eso es lo que está por debajo de todo 00:04:47
Como ya sabemos 00:04:51
Entonces que no queremos hacer nosotros nuestros servlets 00:04:52
Sino que queremos 00:04:54
Una capa que nos facilite el desarrollo 00:04:55
Que no haga mejor la aplicación 00:04:59
Pero si facilite el desarrollo 00:05:01
Pues Spring como tiene de todo 00:05:02
Pues tiene su 00:05:05
Spring MVC 00:05:06
Es decir modelo vista controlador 00:05:07
Tiene su parte 00:05:09
para facilitarte el desarrollo de aplicaciones 00:05:12
con arquitectura modelo vista controlador 00:05:15
que son las aplicaciones web 00:05:17
y los microservicios en general 00:05:18
¿Vale? 00:05:20
Bueno, pues entonces vamos a 00:05:23
a pasarlo, arquitectura de aplicación 00:05:25
modelo vista controlador, lo que es lo mismo 00:05:27
aplicación que va a estar desplegada 00:05:29
en un servidor web 00:05:32
y va a responder a peticiones 00:05:33
y va el controlador 00:05:35
va a recoger esas peticiones 00:05:37
va a cambiar el modelo 00:05:39
o iba a devolver el resultado 00:05:40
pues vamos a pasarlo a esa 00:05:42
arquitectura, entonces como vamos a usar 00:05:44
sprint por 00:05:46
baguería y comodidad y todo eso 00:05:48
y porque realmente es lo que 00:05:50
se usa, pues 00:05:52
ahora ya lo podríamos hacer en nuestro 00:05:54
eclipse de toda la vida, pero si es que es poner 00:05:56
las carpetas y los archivos de configuración 00:05:58
que son uno o dos 00:06:00
uno, pero bueno vamos a hacerlo en el 00:06:02
sprint tools porque 00:06:04
las dependencias realmente y la 00:06:06
creación de las carpetas, pero si es que 00:06:08
ahorras mucho, ahorras 00:06:10
que te mete las dependencias en el POM 00:06:11
porque tú las has marcado en un TIC 00:06:14
y que te hace la arquitectura de carpetas 00:06:16
y te crea un Application Properties 00:06:18
vacío, que lo tienes que rellenar, no ahorras más 00:06:20
en realidad lo estuve con el Application Properties 00:06:22
sí, pero es que eso no me lo habría 00:06:29
arreglado el Sprint Tools 00:06:30
no, me habría dado 00:06:32
un Application Properties vacío 00:06:34
entonces yo, por comodidad 00:06:36
se lo habría pedido otra vez 00:06:38
hacha GPT, lo habría copiado 00:06:40
porque el problema no era el POM, el POM estaba bien 00:06:41
vale 00:06:44
bueno 00:06:46
pues entonces 00:06:48
antes que nada 00:06:49
para hacer nuestras pruebas 00:06:51
y todo eso, vamos a coger una base de datos 00:06:56
sencilla, vale 00:06:58
para 00:06:59
os la puedo 00:07:00
pasar, es esta 00:07:04
alumnos matrículas 00:07:05
pero yo creo que la 00:07:07
hacéis mucho antes, si la escribís 00:07:09
a mano, ¿vale? Mucho antes 00:07:12
por eso no he subido el script, porque 00:07:13
entonces 00:07:15
y luego ya sí que propondremos unas bases 00:07:17
de datos con más relaciones, un poquito más 00:07:25
para ya que trabajéis 00:07:28
vosotros y trabajar de cara a esa 00:07:29
semana que nos queda un poco de repaso 00:07:31
compendio general 00:07:34
de todo esto 00:07:36
alumnos 00:07:37
matrículas, venga 00:07:39
pues esta sencillita 00:07:49
para ver cómo funcionan las cosas 00:07:51
complicar el modelo 00:07:55
no complica la aplicación 00:08:00
en realidad complica 00:08:02
en todo caso la generación 00:08:03
de las clases con las anotaciones 00:08:06
pero es que son cuatro anotaciones que no funcionan igual 00:08:07
vale, pues nada 00:08:10
alumnos matrículas 00:08:14
lo más fácil, alumnos con tres campos 00:08:15
uno clave primaria autoincrement 00:08:18
dos string 00:08:20
y matrículas con cuatro campos 00:08:21
clave primaria autoincrement 00:08:24
y uno de ellos clave ajena alumno 00:08:25
y así tenemos 00:08:27
alumnos que contienen matrículas 00:08:28
y ya está 00:08:32
y la matrícula pertenece a un alumno 00:08:34
una relación de un alumno 00:08:36
muchas matrículas 00:08:38
y ya está 00:08:39
¿qué pasó? 00:08:42
dígame 00:09:48
Sí, los dos, que es la acción más natural. 00:09:49
Al margen de que haya algo que identifique de forma única al alumno, que podría ser el email, 00:09:57
lo normal es que la clave no sea un elemento de negocio, que se llama. 00:10:02
El email es un elemento de negocio, pues tus alumnos tienen email, tienen no sé qué, 00:10:06
sino que sea un código más insignificado. 00:10:10
Y además con la garantía de que sea único, pues autoincrementa. 00:10:13
¿Vale? 00:10:16
claves primaria 00:10:16
información y códigos internos 00:10:19
resto de campos 00:10:21
lógica de negocio de mi aplicación 00:10:22
normalmente, principios 00:10:25
como siempre, principios que luego se pueden 00:10:28
respetar o no, depende 00:10:29
¿eh? 00:10:30
sí, un date 00:10:34
lo he puesto a propósito pues para que tampoco 00:10:35
nos asuste si JPA va a lo va a 00:10:37
pear, sin problema 00:10:39
vale 00:10:40
¿lo tenéis? 00:10:45
Sí, sí, los dos 00:11:24
Lo que decíamos antes 00:11:26
Uy, tenía que haber pausado esto 00:11:28
Venga 00:11:42
Pues ahora 00:11:43
Vamos a empezar nuestro proyecto 00:11:45
¿Vale? 00:11:47
Pues nada 00:11:49
¿Vale? Si estamos en 00:11:50
El Eclipse 00:11:57
¿Vale? Pues en el Eclipse 00:11:58
Para tener la funcionalidad 00:12:01
De un Tomcat embebido 00:12:03
Para poder ejecutarlo 00:12:04
Y todo eso 00:12:06
Y para tener la librería de ese Tomcat 00:12:09
Que necesitamos para todas las 00:12:11
Clasificaciones con HTTP 00:12:13
Si estuvieramos en Eclipse, pues le daríamos el Eclipse ID 00:12:14
Por Web Developer, pues ya está 00:12:17
Ahí hacemos nuestro nuevo 00:12:19
Web Dynamic Project, le ponemos la estructura 00:12:20
De carpetas que nos dé la gana 00:12:23
Y se acabó 00:12:25
Pero si estamos en el este 00:12:26
Pues 00:12:29
Ya sabéis que lo lanzamos así 00:12:30
Porque esto me permite 00:12:32
conectarme a esta página web 00:12:35
que me construye el proyecto 00:12:37
con las dependencias 00:12:39
y yo ya lo 00:12:40
vale, pues este lo voy a llamar clase 00:12:42
vale 00:12:45
llamadlo como te la gane 00:12:47
package 00:12:48
raíz, este 00:12:58
vale, si le queréis quitar el app 00:13:00
que el package raíz sea condam 2, da igual 00:13:02
bueno, pues venga 00:13:04
ahora viene lo interesante 00:13:14
que es, que dependencias vamos a usar 00:13:18
Esta obviamente 00:13:20
Si no os aparece aquí 00:13:23
Porque no habréis usado 00:13:25
Aquí aparecen las últimas que usaste 00:13:27
Si no os aparece nada 00:13:28
Pues ya sabéis que tenéis que buscar 00:13:30
Aquí a mano 00:13:32
Y aquí a mano pues buscáis en SQL 00:13:33
Y os aparece JDBC API 00:13:36
Esta la queremos 00:13:38
¿Qué más queremos? 00:13:39
Spring Data JPA 00:13:42
Lógicamente eso lo vamos a usar 00:13:43
Spring Data JPA 00:13:45
Spring Data JDBC no, recordad que 00:13:47
SpringDapta JDBC era esa capita ligera 00:13:50
Que te 00:13:52
Hacía un ORM ligero 00:13:54
Que vimos en su momento 00:13:56
Que a través de una 00:13:58
Función lambda tú 00:14:00
Hacías a mano la correspondencia entre 00:14:01
Clase y tabla 00:14:04
¿Cómo lo he llamado yo? 00:14:06
A ver, yo lo he llamado unidad 3 res 00:14:09
Alumnos, matrículas, clase 00:14:12
Pero bueno, tú como te quieras organizar 00:14:13
Yo es que lo llamo así porque si no luego no los distingo 00:14:15
Unos de otros ahí 00:14:18
Vale 00:14:19
Esto es por las pruebas que hago en casa 00:14:20
Para no confundir mis pruebas de casa 00:14:22
Que son un mogollón 00:14:24
Con esto que se supone que es más organizado 00:14:25
Vale 00:14:28
Vale 00:14:29
Como estamos usando MySQL 00:14:34
Pues MySQL 00:14:40
Vale 00:14:41
MySQL 00:14:42
JDBC 00:14:45
Todas estas capas las tenemos 00:14:47
JDBC API, Spring Data JPA 00:14:48
Que Spring Data JPA te incluye 00:14:51
Dentro de las de hibernate, porque recordad 00:14:53
Que JPA no es nadie, sin hibernate 00:14:55
Por debajo, toda por libro 00:14:57
Spring Data JPA te lo incluye 00:14:58
Vale, entonces de aquí 00:15:01
Todo, pero es que ahora 00:15:03
Nuestra arquitectura, va a ser una arquitectura 00:15:04
De modelo vista controlador, esto lo vamos a 00:15:07
Ejecutar en un servidor web 00:15:09
Entonces necesitamos 00:15:11
Esta dependencia, vale 00:15:13
La de Spring Web, que esa dependencia 00:15:15
Pues por ahí abajo 00:15:18
Quien no la tenga ahí ofrecida 00:15:19
Pues la tendrá por aquí 00:15:24
¿Vale? 00:15:26
Ah, jolines, está el primero de todos 00:15:32
Vale 00:15:34
En principio 00:15:36
Esto es lo básico, no nos hace falta nada más 00:15:38
Para hacer, en nuestro caso 00:15:41
En lugar de una aplicación web 00:15:43
Que es más pesada, porque tenemos que hacer 00:15:44
El contenido web, las páginas HTML 00:15:46
y luego tenemos que construir 00:15:49
desde el controller el resultado 00:15:52
que es más pesado 00:15:55
porque además si no lo queremos hacer a mano y tenemos que usar 00:15:56
un framework como TimeLeap 00:15:59
pues bueno, tampoco lo conocemos al milímetro 00:16:00
pues vamos a hacer un 00:16:03
servicio, un microservicio 00:16:05
ya está, punto pelota, entonces el microservicio 00:16:06
es mucho más fácil porque 00:16:08
el microservicio 00:16:10
tú no lo llamas 00:16:12
mediante un formulario 00:16:14
que has construido en una página web 00:16:16
al microservicio lo llamas 00:16:18
con una URL directamente, con lo cual 00:16:20
lo puede llamar una aplicación 00:16:22
o lo puedes llamar tú desde el navegador 00:16:24
¿vale? y el microservicio 00:16:26
te devuelve un resultado tal cual 00:16:28
que no es una página web, normalmente si es 00:16:30
un REST o es un JSON 00:16:32
lo que te devuelve, pero hay 00:16:34
más arquitecturas de microservicios 00:16:36
aparte de las API REST, no es 00:16:38
lo único que existe en el mundo 00:16:40
pero efectivamente es la más usada 00:16:41
bueno, pues no necesitamos nada más 00:16:44
para hacer eso, pues venga 00:16:46
Yo creo que esto está todo 00:16:48
Él nos va a hacer nuestro zip 00:16:50
Nos lo va a descargar 00:16:53
Y nos lo va a montar aquí en un ratinín 00:16:55
Así es 00:16:56
Todo por no irnos nosotros 00:16:59
A la página web, ponerle los datos 00:17:02
Y coger el zip y desplegarlo aquí 00:17:04
Que también podríamos hacerlo 00:17:06
De hecho si 00:17:07
Trabajáramos con el eclipse 00:17:09
En lugar de con este 00:17:11
Pues sería tan fácil como irse a esa web 00:17:13
Darle los datos, coger el zip 00:17:15
Y desplegarlo en mi eclipse 00:17:17
Y ya está, estaríamos igual 00:17:19
A partir de ahí ya no 00:17:20
Y interye pues es lo mismo 00:17:21
Vale, pues ya 00:17:26
Nos hizo la aplicación 00:17:34
Entonces, ¿qué arquitectura nos ha puesto? 00:17:36
A ver si no me confundo con la de arriba 00:17:39
En toda la mañana 00:17:41
Nos ha puesto el paquete raíz 00:17:41
Que es el que lanza la aplicación 00:17:46
El que llama Spring Boot 00:17:51
Cuando esta aplicación se lance 00:17:52
Se ejecutará este main 00:17:55
Y este main 00:17:57
Llama Spring Boot automáticamente 00:17:59
Porque para eso está anotado aquí arriba 00:18:01
¿Vale? 00:18:03
Y así se crea ya el contexto 00:18:05
Spring de gestión de 00:18:07
Bins y toda la morralla 00:18:09
Y nosotros ya a partir 00:18:10
De aquí, lo único que tendríamos 00:18:13
Que hacer, si la queremos 00:18:17
Como aplicación 00:18:19
De escritorio 00:18:20
A partir de aquí 00:18:23
Pondríamos ya nuestro código 00:18:25
Nuestra llamada, lo que fuera, ¿vale? 00:18:26
Pero no vamos a ejecutar nuestro servicio 00:18:28
Con aplicación de escritorio 00:18:30
Con lo cual 00:18:31
Capitán 00:18:32
Vale 00:18:36
Bueno, pues nada 00:18:44
¿Qué más nos ha hecho? El properties 00:18:45
Y no nos ha hecho nada, bueno, y el pom 00:18:48
El pom que nos ha metido aquí 00:18:49
Dependencias para aburrir, ¿vale? 00:18:51
Todo esto nos ha metido 00:18:55
Estas miles de millones 00:18:56
Solo para hacer eso 00:18:58
Y nos ha metido el properties 00:19:00
Que el properties 00:19:08
El properties no tiene nada 00:19:09
Entonces el properties no tiene nada 00:19:14
Aquí es donde tenemos que configurar nosotros 00:19:17
Nuestra fuente de datos 00:19:19
Y cualquier otra cosa que queramos 00:19:20
¿Vale? 00:19:22
Entonces 00:19:24
Pues esto, la configuración básica 00:19:24
De la fuente de datos 00:19:27
Que es la única importante 00:19:29
Como tendréis 00:19:30
Tendréis 00:19:33
Algunos de estos proyectos 00:19:36
Lo hicimos aquí 00:19:38
Con lo cual 00:19:39
Ah, pero estos no eran con 00:19:41
El de, no, digo en el trans 00:19:43
El trans lo hicimos aquí 00:19:48
Y en este si usamos base de datos 00:19:50
Porque este era 00:19:52
El de, el que usamos la capa 00:19:53
De Spring JBBC 00:19:57
¿Vale? 00:19:58
Entonces en este que lo debéis tener 00:20:00
Pues pusimos lo 00:20:02
Básico para JDBC 00:20:08
Pues podéis copiarlo y pegarlo 00:20:09
Y nuestra base de datos 00:20:14
Ahora no es coches, sino que es 00:20:19
Alumnos 00:20:21
Barra baja 00:20:23
Matrículas 00:20:24
Si tienes el GPT abierto 00:20:32
Pídeselo y ya está 00:20:35
Vale 00:20:36
Pues esto 00:20:38
Vale, esto sería lo básico 00:20:44
Vale, luego se pueden configurar 00:20:47
muchas más cosas 00:21:03
para Spring Boot, pues relacionadas con 00:21:04
si va a mostrar 00:21:07
el código SQL o no lo va a mostrar 00:21:09
lo que siempre poníamos 00:21:11
si va a crear 00:21:12
la base de datos en caso 00:21:17
de que no esté hecha o no 00:21:19
¿vale? estas cosas 00:21:20
que teníamos yo por ahora 00:21:23
lo vamos a dejar sin poner 00:21:24
porque no sé por 00:21:27
defecto, el show SQL 00:21:29
si queremos que nos lo muestre, pero no sé si por defecto 00:21:31
lo pone a truco no vamos a dejarlo sin poner y si no nos lo sacan las pruebas ya se lo ponemos 00:21:33
para poder ver el log de sql que queremos verlo en las pruebas por ahora ponemos lo mínimo y se 00:21:37
acabó vale estamos en modo examen vale venga pues entonces ahora ya sí que si empezamos a 00:21:42
a hacer nuestra aplicación y siempre 00:21:52
lo primero es 00:21:54
el modelo. 00:21:56
El modelo, ¿vale? 00:22:03
Pues venga. 00:22:07
Esto como de las cartetas, porque 00:22:08
era como que tenía que ser... 00:22:10
Claro, si es Spring Boot, 00:22:12
si no es Spring Boot, no, porque tú en la configuración 00:22:14
ya haces un componente scan y ahí puedes 00:22:17
poner los paquetes base que te den la gana. 00:22:18
Pero si es Spring Boot, 00:22:21
Spring Boot necesita que 00:22:22
todo cuelgue de donde 00:22:24
creas el contexto. Si el 00:22:27
contexto está creado en condam2app 00:22:29
el resto de paquetes donde hay 00:22:31
beams 00:22:33
escaneables tiene que ser ahí. 00:22:35
¿Vale? 00:22:38
Entonces 00:22:39
con.dam2.app 00:22:40
.model 00:22:43
¿Vale? 00:22:44
Nos ponemos todos desde app. 00:22:47
A ver, no es necesario que 00:22:48
estuvieran todos. En realidad solo los que tienen 00:22:51
beams que va a gestionar sprint. 00:22:53
Pero un poquito también para 00:22:55
Coherencia un poco del modelo 00:22:56
Y por todo 00:22:59
Venga, pues aquí, el modelo de esto 00:22:59
Vamos a hacer 00:23:02
Seguramente más rápidos 00:23:05
Haciéndolo a mano 00:23:06
Poniéndole una foto a HGPT del diagrama 00:23:07
Y que nos lo deis en anotaciones para anotarla 00:23:11
¿No? Vamos a hacer seguramente 00:23:13
Pues venga, vamos a empezar 00:23:15
Con, yo que sé, con alumnos 00:23:16
Por ejemplo 00:23:19
Pues hacemos nuestra nueva clase 00:23:20
Alumno 00:23:23
Vale 00:23:25
Nuestra clase alumno tiene 00:23:25
Su ID 00:23:30
¿Eh? 00:23:34
Supongo 00:23:41
A ver, supongo porque le pasamos el script 00:23:42
El otro día y el 00:23:45
ChaGPT nos lo devolvió como long 00:23:46
Pero vamos, tiene toda la pinta 00:23:48
Pero en cualquier caso 00:23:50
Los mapeos entre enteros 00:23:53
Son relativamente flexibles 00:23:54
Si, pero si no ponen 00:23:56
Si ponen 00:23:59
Ya, bueno 00:24:01
Nombre, hemos dicho 00:24:08
E-mail 00:24:11
Estas serían las tres propiedades que tiene alumno 00:24:14
Y ya podemos avanzar 00:24:17
Que tiene 00:24:19
¿El qué? Una lista de matrículas 00:24:20
Porque hay una clave ajena 00:24:23
Matrícula, ya podemos avanzar esto 00:24:24
Matrículas 00:24:29
Y ya que estamos 00:24:31
Pues vamos a asegurarnos 00:24:34
Una inicialización 00:24:37
Vale 00:24:38
El constructor sin parámetros 00:24:46
Ya sabemos que cuando se trata de hibernate 00:24:49
El constructor sin parámetros 00:24:50
Tardo o temprano te lo va a pedir 00:24:52
Porque hibernate instancia siempre con constructor sin parámetros 00:24:54
Con lo cual 00:24:57
Si yo lo dejo así, vale 00:24:58
Pero si le pongo un constructor con parámetros 00:25:00
Que 00:25:02
Eso sí ya, que puede ser útil 00:25:03
Por código, pues entonces 00:25:06
le voy a quitar en el constructor este 00:25:08
esto que es muy feo, instanciar un alumno ya con sus matrículas 00:25:14
es un poco feo, y hacemos el constructor normal 00:25:19
y los get y set 00:25:23
de todo, antes de empezar con las anotaciones vamos a hacer la matrícula 00:25:32
para que se nos quite este error, matrícula 00:25:57
y matrícula tenía su id también 00:26:07
Long porque hemos puesto 00:26:12
Bing Hint en el otro lado 00:26:17
Nombre, o no sé cómo se llamaba 00:26:18
Ese campo, pero da igual cómo se llame 00:26:23
Porque se llama asignatura 00:26:25
De todas formas, vamos a cambiarlo 00:26:27
Aquí, que es un poco feo 00:26:29
Nombre 00:26:30
No, nombre de la matrícula es feo 00:26:31
No, no, no, está mucho mejor pensado 00:26:37
Asignatura, claro, con razón lo llamamos así 00:26:38
Vale, la matrícula 00:26:40
Es de una asignatura 00:26:43
Y tiene una fecha 00:26:43
Vale 00:26:46
Podríamos usar date y Bernat la va a mapear 00:26:47
Pero bueno, local date 00:26:50
Está un poco más actualizada 00:26:52
Local date es de java time 00:26:54
Y date es de java útil 00:26:57
Que es la que se ha usado de toda la vida 00:26:59
Pero java time es un paquete 00:27:00
Un poquito más actualizado para trabajar con fechas 00:27:02
A la fecha de la matrícula 00:27:05
Y ya sabemos 00:27:08
Que la matrícula pertenece a un alumno 00:27:12
Porque es una relación de uno a muchos 00:27:15
Nos hacemos el constructor 00:27:17
Este que si no 00:27:29
Nos lo va a pedir cuando tenga que instanciar 00:27:38
Una matrícula nueva 00:27:40
Para 00:27:41
Mapearla 00:27:42
Get y set 00:27:45
Y a falta de hashCode, equal to string 00:27:47
Esos tres métodos básicos 00:27:57
A falta de eso 00:27:59
Que vamos a dejarlos para 00:28:00
Si luego los necesitamos 00:28:03
Aunque 00:28:05
Dejar entidades sin el equals 00:28:05
Es un poco peligroso 00:28:09
Pero bueno, vamos a dejarlo así 00:28:10
A ver si detectamos 00:28:12
Tenemos algún mal funcionamiento 00:28:13
Y acabamos deduciendo que falta el equals 00:28:15
Porque eso sí que nos va a hacer 00:28:18
Aprender algo 00:28:20
Somos conscientes de la importancia del equals 00:28:21
Y para qué sirve 00:28:24
Pero lo dejamos así 00:28:24
Pues hemos lanzado 00:28:27
Vale, ahora ya sí que nos ponemos a anotar 00:28:30
Pues venga 00:28:33
Matrícula 00:28:34
Es una entidad 00:28:36
¿Vale? 00:28:38
Pero, matrícula 00:28:40
La tabla no se llama matrícula 00:28:42
Sino que se llama matrículas 00:28:45
Entonces 00:28:46
Pues le ponemos nuestro nombrecito 00:28:48
Matrículas 00:28:52
Vale, y esto 00:28:53
De Yakarta Persistence 00:28:57
Muy bien 00:28:59
Ah, no he mirado aquí por curiosidad 00:29:00
En qué me ha puesto la máquina 00:29:02
Ah, en la 21, vale 00:29:03
Vale, matrículas 00:29:05
Ahora los campos 00:29:08
El IDE es clave primaria 00:29:09
Pues si es clave primaria 00:29:11
Ya sabemos que se anota con IDE 00:29:13
Y ya sabemos 00:29:15
Que si es autoincrement 00:29:18
Había que poner 00:29:20
No sé qué 00:29:21
Clash patatín 00:29:23
Que 00:29:25
El generated value 00:29:26
Venga, ahí que tenemos 00:29:30
Tres horitas estupendas 00:29:34
Vamos a usarlo para poner las cosas un poco más a mano 00:29:35
Y así 00:29:38
Que la memoria 00:29:39
Juanfi coge la tercera hora de hoy 00:29:42
Eso cuando os lo dijo 00:29:47
No, a ver 00:29:49
Claro, es que yo daba por sentado que esta hora 00:29:57
Como Alejandra me la regala siempre que quiero 00:29:59
Yo daba por sentado que esta hora siempre que podía cogerla 00:30:00
La cojo 00:30:03
Pero 00:30:03
Igual es que Juanfi no sabe que yo la cojo 00:30:05
De vez en cuando 00:30:08
O sea, lo de Juanfi está confirmado 00:30:09
Bueno, a ver 00:30:12
Tú quieres ver la sangre 00:30:16
¿No? 00:30:22
Por la pelea 00:30:25
¡Hala! 00:30:30
Esto era 00:30:31
Cuidado con las anotaciones 00:30:32
¿Vale? 00:30:40
Con los import, me refiero 00:30:42
Cuidado con los import 00:30:43
Vale 00:30:45
Espera, no, no, no 00:30:45
Espérate 00:31:00
Perdón, perdón, perdón 00:31:01
Que me he metido con Spring aquí, perdón 00:31:02
Y no estoy con Spring ahora, estoy con JPA 00:31:04
¿Vale? Sí, adelante 00:31:06
00:31:08
¿Vale? 00:31:11
Cuidado con los import 00:31:14
Que estos errores son típicos 00:31:16
Yo ahora estoy en JPA 00:31:18
Esto no es Spring ni es nada 00:31:20
Entonces, de lo que me ha ofrecido 00:31:22
Como yo estoy con el chip ya de que está metido con Spring 00:31:24
Me he metido aquí, pero que no 00:31:27
Esto es JPA 00:31:28
Esto es JPA 00:31:31
Con lo cual esto es de Yacarta 00:31:32
¿Vale? 00:31:33
Podría a lo mejor esto haberme dado un error 00:31:35
Más adelante 00:31:37
Y haberme estado, ni se sabe, hasta que me he dado cuenta 00:31:38
De que estaba importando el ID del sitio 00:31:42
No correcto, ¿vale? 00:31:43
Situación habitual 00:31:45
Ya está 00:31:46
Y hay que cambiar algo más 00:31:50
Se llaman todos los campos igual 00:31:54
¿Verdad? 00:31:56
¿Vale? Pero tenemos la clave 00:31:57
¿Alumno? 00:31:59
Ah, la clave, sí, pero tenemos la clave 00:32:01
El nombre de los campos 00:32:04
Son igual, pero tenemos ya una clave ajena 00:32:06
Que es lo que nos falta 00:32:08
Entonces la clave ajena viene por aquí 00:32:09
Entonces 00:32:11
Esta es, muchas matrículas 00:32:12
Pueden pertenecer a un mismo alumno 00:32:16
Luego entonces, aquí 00:32:17
Many to one, ¿vale? 00:32:20
Y aquí es donde 00:32:22
Configuramos 00:32:23
La columna 00:32:25
Joint column 00:32:27
vale, entonces la columna 00:32:30
que está en la tabla matrículas 00:32:33
la columna que está en la tabla matrículas 00:32:36
porque estamos en la clase matrículas 00:32:38
que sería alumno ID 00:32:40
suponemos 00:32:41
vale 00:32:42
y aquí 00:32:44
podemos configurar unas cuantas cositas 00:32:46
si nos da la gana 00:32:50
el fetch type en el extremo 00:32:51
many to one, recordad que 00:32:54
por defecto es eager, con lo cual 00:32:55
carga siempre al alumno 00:32:58
queremos que cargue siempre al alumno 00:32:59
cuando recuperemos 00:33:02
una matrícula 00:33:04
siendo uno 00:33:06
no es grave, podemos dejarlo por defecto 00:33:08
vale 00:33:10
hay más campos que se pueden 00:33:11
configurar aquí 00:33:15
pues el 00:33:17
el opcional, por ejemplo 00:33:18
el opcional, si este campo 00:33:21
es opcional o no 00:33:23
entonces bueno 00:33:26
Ahora mismo no hay nada 00:33:29
El FaceTag no es importante 00:33:30
No hay nada que nos importe especialmente 00:33:32
Entonces lo podemos dejar así 00:33:34
Y ya está 00:33:36
Nos vamos a matrícula 00:33:37
Alumnos 00:33:42
Aquí ya vamos a copiar esto 00:33:43
Lo copiamos en ID 00:33:47
Copiamos lo de Entity de matrícula 00:33:51
Cambiando el nombre 00:33:55
Alumnos 00:33:55
Algún este cambia de nombre 00:34:04
Yo creo que no hay ninguno que cambie de nombre 00:34:10
¿Verdad? 00:34:12
Entonces 00:34:15
La relación 00:34:15
Es lo único que nos falta 00:34:19
¿Verdad? La relación 00:34:20
Entonces, este es el otro extremo 00:34:21
Y este extremo significa 00:34:24
Que es un alumno, muchas matrículas 00:34:25
Aquí por defecto es lazy 00:34:29
Con lo cual no hace falta que lo pongamos 00:34:31
Pero lo que sí que tenemos que poner 00:34:33
Es quién ha mapeado 00:34:35
Quién mapea 00:34:38
Quién informa de esto 00:34:39
Pues de esto, ¿quién informa? 00:34:41
El campo alumno de la clase matrícula 00:34:44
El campo alumno de la clase matrícula 00:34:48
Pues entonces ponemos aquí nuestro alumno 00:34:50
¿Verdad? 00:34:53
Y aquí también, el fetch type como por defecto es lazy 00:34:59
Pues vamos a dejarlo en lazy 00:35:10
Que no cargue todas las matrículas 00:35:11
Que cogemos un alumno, por ejemplo 00:35:13
Si queremos que se carguen 00:35:16
Pues o nos hacemos una consulta específica con el join fetch 00:35:18
o trabajamos dentro de la misma transacción en el mismo método 00:35:22
sin cerrar la transacción, porque el problema del lazy 00:35:26
es cuando pides las matrículas si el contexto de presidencia 00:35:30
se ha cerrado, es decir, si estás ya fuera del método, pero si estás dentro del método 00:35:34
tú puedes pedir tranquilamente las matrículas y no pasa nada por muy lazy que sea 00:35:38
aquí también se podría configurar el parámetro cascade 00:35:41
para ver si borrar alumnos borra las matrículas 00:35:46
Si insertar alumnos, si inserta las matrículas 00:35:50
Recordad que esto en pruebas 00:35:53
Normalmente 00:35:54
Se hace así 00:35:55
¿Verdad? 00:35:59
Cascade punto 00:36:03
Cascade type 00:36:04
Sí, punto 00:36:05
Vale, que me haga cascada 00:36:08
Del persist, del remove, de todo eso 00:36:11
Pues 00:36:13
Si, opcional 00:36:15
Unix, bueno, unix aquí con una lista 00:36:16
Hace mucha falta, el orphan removal 00:36:19
También es un parámetro que se pone a veces 00:36:21
¿Vale? Recordad 00:36:23
Que el orphan 00:36:24
Removal 00:36:26
Lo puedes poner a true o a false 00:36:28
¿Vale? En función de 00:36:32
Una matrícula se ha descolgado 00:36:36
De su alumno porque le hemos quitado la colección 00:36:39
Si esa matrícula queremos que desaparezca 00:36:40
Normalmente las relaciones de uno a muchos pues las ponemos así 00:36:42
Bueno 00:36:44
Y en principio hemos acabado 00:36:46
Con esta 00:36:48
Está mapeada por alumno de matrícula 00:36:49
Si hemos hecho algún error 00:36:53
Ya nos lo va a decir 00:36:55
¿Vale? Con suerte hemos cometido alguno 00:36:56
Y lo podemos arreglar 00:36:58
Bueno 00:36:59
Y ahora viene lo facilito 00:37:00
Y lo chuli 00:37:04
Lo que más satisfacción da es escribir cosas 00:37:05
Y que te lo hagan todo solo 00:37:07
¿Qué es lo siguiente que hacemos después del modelo? 00:37:08
Permisión 00:37:13
¿Eh? 00:37:13
Normalmente haríamos el DAO 00:37:15
Pero aquí hacemos el repositorio 00:37:16
Ah, muy bien pensado 00:37:19
Efectivamente 00:37:32
Recordad, claro 00:37:33
Que aquí tenemos una relación 00:37:35
De uno a muchos 00:37:40
Eso significa que 00:37:41
En una relación de uno a muchos 00:37:42
Hay uno que es el que manda 00:37:45
El propietario de la relación 00:37:47
¿Y quién era el propietario de la relación? 00:37:49
¿El extremo de él? 00:37:52
Vale 00:37:57
Entonces 00:37:58
Ese es el que manda la relación 00:37:58
A partir de la cual 00:38:01
Se tienen que hacer las modificaciones 00:38:02
El que manda 00:38:05
Entonces, si nosotros añadíamos 00:38:06
Una matrícula a un alumno 00:38:09
No, no, no 00:38:11
Según me lo decías 00:38:15
No, no, no, estaba dudando 00:38:16
Claro, la parte que manda es esta 00:38:18
La parte que manda es esta, la del many 00:38:21
¿Vale? Entonces, ¿cuál es el problema de que la parte 00:38:23
Que manda, la propietaria de la relación 00:38:26
Es la del many? Entonces 00:38:27
¿Eso qué significa? 00:38:29
Que si nosotros, es la que tiene 00:38:31
La clave ajena, es la que manda 00:38:33
Porque alumno va por libre, alumno, si uno mira aquí 00:38:35
¿Vale? 00:38:38
Alumno, no sabe nada 00:38:40
De matrícula, ni le importa 00:38:41
Matrícula, sí, matrícula es la que 00:38:43
Decide, oye, yo pertenezco a ti 00:38:45
Soy clave ajena, pues yo soy la propietaria 00:38:47
para JPA, esa es la regla 00:38:50
yo soy la propietaria porque yo tengo la clave ajena 00:38:52
yo soy la propietaria, eso que implica 00:38:53
que si tú vas 00:38:56
desde alumno, añades 00:38:57
una matrícula 00:39:00
esa matrícula 00:39:01
no va a coger, y haces el 00:39:03
persist, esa matrícula 00:39:06
no va a coger la clave 00:39:08
ajena, no se va a hacer 00:39:10
en SQL, no se va a hacer el set 00:39:11
de este alumno ID, no se va a hacer, es SQL 00:39:13
no se va a hacer, sin embargo al revés 00:39:16
sí. Si tú haces persistencia 00:39:18
de una... Es que al revés 00:39:20
no se tiene que hacer nada. Si tú haces persistencia de una 00:39:22
matrícula y fijas un alumno, el alumno 00:39:24
es que no tiene que cambiar nada. 00:39:26
No tiene que cambiar nada. Por eso esta es la 00:39:28
propietaria, porque esta es la que necesita 00:39:29
que se le haga el SQL, la que se 00:39:32
le necesita. Entonces, 00:39:34
el problema se manifestaba 00:39:36
en que 00:39:38
si nosotros hacemos, efectivamente, 00:39:39
añadimos una matrícula 00:39:41
y hacemos un merge o un 00:39:43
commit para que se actualice el objeto alumno, 00:39:46
Pues esto no va a aparecer aquí 00:39:48
Entonces hay que fijárselo específicamente 00:39:50
Y para eso 00:39:52
Era cómodo 00:39:54
Para no tener que hacerlo 00:39:57
Siempre por código 00:39:58
Era cómodo pues hacer algo así 00:39:59
Public void 00:40:02
En alumno 00:40:04
Add matricula 00:40:05
Matricula 00:40:07
Y ahora 00:40:12
Que hacíamos aquí 00:40:14
matriculas.add 00:40:18
matricula 00:40:23
y ahora 00:40:24
m.set 00:40:26
alumno 00:40:29
vale 00:40:30
this, ¿verdad? 00:40:32
no se me olvide nada, ¿no? 00:40:39
vale, y cuando borramos 00:40:41
lo mismo, si quitamos una matricula 00:40:45
el objeto matricula necesita su propio 00:40:47
SQL 00:40:51
Para perder esta clave 00:40:51
Entonces 00:40:56
Matrícula 00:41:01
Matrícula M 00:41:11
Entonces 00:41:13
Aquí ahora ya sí 00:41:15
Matrículas 00:41:16
Matrículas 00:41:18
Matrículas no 00:41:20
Matrículas.remove 00:41:21
Y ahora 00:41:30
Necesito que matrícula se entere 00:41:32
Porque desde alumno no puedo 00:41:34
tocarla. Y para que matrícula 00:41:36
se entere, pues entonces 00:41:40
set alumno nulo. 00:41:41
Tú ya no perteneces 00:41:43
a este alumno. 00:41:45
Vale. 00:41:49
Entonces, ¿cómo? Esto tiene 00:41:50
sentido porque matrícula 00:41:51
¿eh? 00:41:53
Justo. Sí, sí, sí. Eso lo iba a decir 00:41:59
ahora. Si esto, el poner esto aquí 00:42:01
nos despertaba unas alarmas. 00:42:03
Si os las despierta, ¿verdad? 00:42:05
Y aparte, para que esto también 00:42:07
tenga sentido, matrícula 00:42:09
Tiene que tener esto como opcional 00:42:10
¿Verdad? El alumno 00:42:14
Que no se lo hemos puesto 00:42:15
Opcional 00:42:17
Igual a true 00:42:19
¿Vale? 00:42:21
Opcional 00:42:23
No es 00:42:23
Es opcional ¿Verdad? 00:42:24
Ah, perdón 00:42:27
Es que será aquí 00:42:29
Supongo 00:42:31
Control X 00:42:31
Vale, es que sí 00:42:36
Ahí, vale 00:42:37
Venga, pues ala 00:42:39
Y entonces, efectivamente, aquí se nos ha despertado ya la angustia de, uy, este remove solamente va a funcionar si tengo el equals y no va por dirección de memoria, pues bueno, como nos cuesta nada, generamos equals por id y ya que estamos en alumno también, generamos equals por id, vale, y este overwrite porque me da problemas. 00:42:45
No sé por qué se ha puesto tonto ahora 00:43:51
No sé por qué se me ha puesto tonto 00:43:53
Pero vamos, que esta anotación me da lo mismo 00:44:07
Es informativa 00:44:09
Pero no sé por qué se ha puesto así 00:44:09
Habría que mirarlo 00:44:13
¿Vale? Pero bueno, como es informativa no da igual 00:44:14
Pues... 00:44:17
Vale 00:44:19
Bueno, pues nuestro repositorio famoso 00:44:19
Ay, perdón 00:44:23
Pues nada, nuestro interfaz 00:44:36
Alumno 00:44:45
Repositori 00:44:49
Repositori 00:44:51
Le llamo como me da la gana, lógicamente 00:44:53
Pero bueno 00:44:56
Es habitual llamarlo así 00:44:57
Y este que herede de 00:45:00
Alumno 00:45:02
Repositori 00:45:04
Uy, que 00:45:06
De JPA, de JPA 00:45:08
Que sí, que sí, a ver 00:45:10
No me hagáis mucho caso 00:45:12
Porque entre que me doy la garganta y he dormido dos horas 00:45:15
No sé muy bien lo que estoy diciendo 00:45:17
Pero como estáis muy despiertos 00:45:19
Pues 00:45:20
Vale 00:45:21
Long y alumno 00:45:23
Primero la entidad y luego la clave 00:45:26
Tienes razón 00:45:32
El tipo de la clave 00:45:33
Vale 00:45:37
Repository 00:45:38
Ala, ahí lo tenemos 00:45:45
Y aquí 00:45:49
Tenemos los métodos básicos 00:45:51
Lógicamente 00:45:54
Vamos a hacer la matrícula repository 00:45:55
También 00:45:57
Este no hay que anotarle con repository 00:45:58
Se infile directamente de aquí 00:46:00
Vamos a hacer el repository del otro 00:46:01
Repository 00:46:05
Ahora lo cambio 00:46:18
Vale, y esto es 00:46:19
De matrícula 00:46:36
Bueno, pues antes de meter más métodos 00:46:39
En estos repositorios 00:46:47
Para hacer cosas más raras con el servicio 00:46:49
Y todo eso, antes de hacerlo 00:46:50
Vamos a dejarlo, vamos a hacer 00:46:51
Un servicio, un controlador y lo probamos 00:46:54
Ahí todo funciona 00:46:56
Y luego ya nos ponemos a meter aquí más métodos 00:46:57
Y más cosas que nos interesa 00:47:00
Vender, ¿vale? 00:47:01
Bueno, pues ahora este repositorio 00:47:04
Va a ser llamado a través de unos servicios 00:47:05
Está claro 00:47:08
Pues venga, vamos a hacernos 00:47:09
Uy, el paquete 00:47:11
App.service 00:47:16
Pues venga 00:47:31
Alumnoservice 00:47:40
Vamos a hacer cosas con alumno 00:47:43
Entonces, esta sí que hay que anotarla 00:47:45
para que 00:47:50
Spring la maneje 00:47:52
y la inyecte cuando sea necesario 00:47:54
y aparte pues para poder 00:47:56
bueno no, para usarla 00:47:58
y para poder usar las notaciones transactional dentro 00:48:00
y todo eso 00:48:02
entonces alumno service ¿quién va a necesitar? 00:48:03
pues alumno service va a necesitar 00:48:06
a un alumno repository 00:48:08
y puede que a un matrícula repository también 00:48:11
pero bueno por ahora 00:48:14
RepoAlumno 00:48:16
RepoAlumno 00:48:21
Vale 00:48:24
Que se lo vamos a pasar 00:48:25
Por constructor 00:48:27
Se lo pasamos por constructor 00:48:30
Y ya está 00:48:36
Que es lo habitual 00:48:40
Ahí está, por constructor 00:48:41
Y ahora vamos a hacer un primer servicio básico 00:48:42
Que es 00:48:45
PublicAlumno 00:48:46
GetAlumno 00:48:50
Por ejemplo 00:48:54
getAlumno 00:48:54
a través de su clave 00:48:57
y ahora 00:48:59
este 00:49:02
yo llamo a repo 00:49:04
alumno 00:49:07
.find 00:49:07
by id 00:49:12
que estará por ahí 00:49:13
abajo, find by id 00:49:16
y le paso id 00:49:18
vale, entonces 00:49:19
este 00:49:21
punto 00:49:24
Or else 00:49:25
¿Vale? 00:49:27
Vamos a hacer 00:49:31
Para, hombre, jugar un poco 00:49:32
Que tampoco estamos un poco 00:49:35
Le podríamos devolverle el get 00:49:37
Con lo cual propago lo del null de toda la vida 00:49:39
Pero vamos a decir que si no lance una excepción 00:49:41
En lugar de una genérica 00:49:43
Que lance una que construyamos nosotros 00:49:45
Aquí lo, ¿Ves? 00:49:47
¿Veis? 00:49:48
El or else throw 00:49:50
Me dice, si me das un supplier 00:49:51
yo te lanzo la excepción 00:49:54
de este supplier, entonces un supplier 00:49:58
que es una lambda 00:50:00
que no recibe nada y te genera algo 00:50:01
eso es un supplier 00:50:03
pues entonces, la lambda que tenemos 00:50:05
que poner nosotros aquí 00:50:08
pues es una lambda que no recibe 00:50:09
nada y genera algo 00:50:13
¿qué queremos que genere? 00:50:15
la excepción nuestra propia 00:50:17
porque estamos obviando hacer nuestras excepciones 00:50:19
pero en cualquier aplicación 00:50:21
uno no tira 00:50:23
Para comunicarse de las excepciones 00:50:24
Ya hechas, ni obviamente 00:50:27
De existenado ni nada de eso 00:50:29
Tira de lanzando excepciones suyas 00:50:30
Que se refieren a su negocio 00:50:32
Pues en este caso podríamos hacer 00:50:34
Alumno no existe 00:50:35
Exception, que esta lógicamente 00:50:38
No la tiene Java 00:50:40
Vale, pues entonces 00:50:40
Yo aquí tengo ya mi supplier 00:50:44
Entonces 00:50:46
Mi objeto alumno que voy a devolver 00:50:47
Es este 00:50:50
Si no está 00:50:54
Lanzaré una excepción 00:50:56
Que ahora construimos, que no pasa nada 00:50:57
Ay, pínchate ahí 00:50:59
Vale 00:51:02
Y ahora yo 00:51:03
Devuelvo el alumno si es que no he salido 00:51:05
Antes por la excepción, lógicamente 00:51:08
Entonces vamos a hacer 00:51:10
La excepción 00:51:11
Aquí lo normal es que aquí 00:51:13
Hubiera un paquete 00:51:16
Con las excepciones, que pueden ser 00:51:17
Ciento y la madre 00:51:19
Y en mi paquete excepción, pues yo ya 00:51:20
Me hago 00:51:29
Alumno 00:51:32
No existe 00:51:34
Exception 00:51:36
Alumno no existe exception 00:51:38
Exception 00:51:45
Necesita 00:51:52
Su constructor 00:51:53
Exception 00:51:55
El constructor voy a usar 00:52:03
Sin parámetros para ya directamente 00:52:05
Poner aquí el mensajito que yo quiera 00:52:07
no existe 00:52:09
alumno 00:52:13
esta es mi excepción, bien hecha 00:52:14
pero si yo dejo la excepción así 00:52:19
como era 00:52:22
de esperar 00:52:24
bueno, primero voy a importar el alumno 00:52:25
no existe excepción, vale 00:52:27
si yo dejo mi excepción así 00:52:29
como era de esperar, me dice, oye este método 00:52:31
puede que la hace excepción 00:52:34
entonces capturarla 00:52:36
es completamente absurdo 00:52:37
Generamos un mensaje 00:52:39
Para amordazarnos luego 00:52:43
Pues para qué sacamos el mensaje si no vamos a amordazar 00:52:45
Que es lo que hace el try catch, te amordaza 00:52:47
Pues un throw 00:52:49
Pero aquí ya en una arquitectura con tantas capas 00:52:50
De no sé qué, de patatín, me comunico 00:52:53
Esto en realidad, quién lo va a llamar 00:52:55
Lo va a llamar un controller 00:52:57
No lo vamos a 00:52:58
Poner aquí un throw, esto ya sí que mete 00:52:59
Basura 00:53:03
Entonces 00:53:04
¿Qué alternativa tenemos? 00:53:06
Ni un try catch 00:53:08
Ni throw ni try catch 00:53:10
Muy bien 00:53:11
Cambiarla a runtime exception 00:53:16
Muy bien 00:53:18
Eso es una memoria 00:53:19
Muy interesante 00:53:22
Un ejercicio de memoria 00:53:23
Bueno, las excepciones de runtime 00:53:25
No había por código 00:53:27
Que capturarlas ni programarlas 00:53:29
Y esto es lo habitual 00:53:32
En una arquitectura de estas 00:53:34
Porque no tengamos que arrastrar los throws 00:53:35
Runtime se ocurre 00:53:36
Ya está, que salte 00:53:39
Como que igual salta, pues no debería 00:53:41
No me desconciertes 00:53:47
Que no estamos para eso 00:53:49
Ya, tú lo que quieres es asustar 00:53:50
Vale 00:53:57
Bueno, entiendo que 00:53:59
No necesitamos parar, ¿no? 00:54:04
¿Verdad? 00:54:07
Bueno, pues ahora 00:54:11
Ahora sería cuando nosotros desde nuestro main 00:54:12
Dime 00:54:14
¿Qué he hecho? 00:54:15
¿Este? 00:54:18
Ah, el, espera, lo voy a pasar aquí debajo 00:54:20
Para que se vea mejor 00:54:21
Or else throw es un método 00:54:22
Que necesita un supplier 00:54:25
Que es 00:54:27
Dame algo sin que yo te dé nada 00:54:28
¿Qué me tienes que dar? 00:54:31
Algo que herede de excepción 00:54:33
¿Vale? Esa excepción será lanzada 00:54:34
Si no existe la look 00:54:37
Y hombre, mejor esto que un get 00:54:39
¿Verdad? 00:54:41
Mejor te aviso con una excepción 00:54:42
Y tú ya verás que haces con ese desastre 00:54:44
Que no te doy un null 00:54:46
Y... 00:54:47
A ver, no es igual 00:54:49
No, hombre, no es lo mismo 00:54:54
Un error de un null pointer exception 00:54:56
Que una excepción alumno no existe 00:54:58
Ya, pero no 00:55:01
Pero no ves la línea 00:55:06
O sea, tú piensa que esto no 00:55:08
Esto es un código pequeño 00:55:09
Pero esto puede formar parte de una aplicación 00:55:11
Claro, entonces la comunicación 00:55:13
Tiene que estar un poco más 00:55:16
Más organizada 00:55:17
Bueno, pues entonces 00:55:19
Ahora sería cuando nosotros 00:55:22
Nos pondríamos con nuestro main 00:55:24
A probar 00:55:26
A ver si hemos hecho las excepciones bien 00:55:28
O no 00:55:30
Entonces 00:55:30
Bueno, vamos a hacerlo rápidamente 00:55:32
Para detectar si hay alguna notación que está mal hecha 00:55:35
Antes de seguir con el controller 00:55:38
Vamos a hacernos, bueno, si ya tenemos el main 00:55:40
Que tontería, que hago 00:55:42
Nos vamos a hacer rápidamente 00:55:42
Este que me saca 00:55:46
Una application 00:55:48
Vamos a recoger el application context aquí 00:55:49
Para sacar el bin 00:55:51
Application context 00:55:53
Este lo vamos a sacar 00:56:02
Application 00:56:04
Vale 00:56:06
Application context 00:56:08
Spring framework 00:56:11
Vale, entonces vamos a sacarla 00:56:12
Para ahora sacar el bin 00:56:15
Del service 00:56:17
el service que es alumno 00:56:18
service 00:56:23
application 00:56:24
context punto get 00:56:33
bin 00:56:35
get bin 00:56:35
alumno service punto 00:56:38
class, venga, sácame 00:56:40
este bin con todo lo que 00:56:45
cuelgue de él, con todo 00:56:47
y ahora ya vamos a 00:56:48
probar 00:56:51
a ver 00:56:51
service punto get 00:56:53
alumno 1 00:56:57
alumno 1 00:56:58
ah, vale, porque la L 00:57:05
vale 00:57:07
bueno, no sé si vosotros 00:57:09
no tendréis alumnos metidos 00:57:13
meted uno cualquiera rápidamente 00:57:15
yo mientras voy probando a ver si esto 00:57:17
funciona 00:57:20
venga, pues sprint se lanza 00:57:21
blu, blu, blu 00:57:31
perfecto 00:57:33
todas nuestras anotaciones, aquí está el alumno 00:57:34
como no tengo un toString, pues vaya patata 00:57:37
pero bueno, me ha recuperado un alumno 00:57:40
lógicamente, no tengo un toString 00:57:42
vale 00:57:44
no veo aquí el 00:57:47
select, con lo cual la opción 00:57:52
de showSQL por defecto no está 00:57:54
true, luego vamos a ponérsela 00:57:56
al properties, porque es que 00:57:58
si no, pues 00:58:00
que yo aquí 00:58:01
no he visto 00:58:04
el select no sé qué, todo lo que me 00:58:06
sale que es lo que está haciendo Ibernate para controlar 00:58:08
porque la opción showSQL 00:58:10
No está puesta 00:58:12
Entonces, como sí que nos interesa 00:58:13
Volver las cosas 00:58:16
Vamos a ponérsela en el Application Properties 00:58:17
¿Qué? Application Properties 00:58:20
Que esta 00:58:23
Se llamaba, ¿tenéis ahí a mano algún? 00:58:25
A ver 00:58:34
Es que es por no abrir 00:58:35
Ah, bueno, yo lo tendría aquí arriba 00:58:37
Supongo 00:58:39
Sí, un momento 00:58:41
Un momentito, porque 00:58:43
No, pues aquí tampoco lo puse 00:58:44
Pase de todo 00:58:47
Es que tendría que abrir el eclipse para 00:58:49
Para acordarme la propiedad 00:58:51
O preguntarse al HGPT 00:58:54
Que no le estamos preguntando nada 00:58:55
Y se va 00:58:57
Y se va a aburrir 00:58:58
Vale, espera, mientras lo copias 00:59:00
Tú, Cristina 00:59:05
Voy a pedírselo al HGPT 00:59:06
Que estará diciendo 00:59:09
Martes, 3 primeras horas de la mañana 00:59:10
Y no me preguntas 00:59:13
¿Qué está pasando? 00:59:15
Vale 00:59:16
Aplicación 00:59:25
Punto properties 00:59:29
Típico 00:59:32
Vale, ya está 00:59:33
Vale, le he pedido 00:59:39
¿Se puede saber por qué me hablan italiano? 00:59:42
A veces 00:59:46
Porque no he puesto la tilde 00:59:47
El típico 00:59:50
Bueno, pues nada 00:59:50
Me ha confundido con Estefano 00:59:53
Vale, pues entonces 00:59:57
Esto era, venga 00:59:59
Estas, tres de aquí 01:00:01
Ala 01:00:06
Vale, DDL auto 01:00:07
Que la actualice si cambia 01:00:14
SOSQL true 01:00:15
Y que me lo formate true 01:00:17
Pues venga, ahí está mi selleta 01:00:19
Vale, mucho más bonito así 01:00:30
¿Eh? Acabáis antes y se lo preguntáis 01:00:33
A Chajerito 01:00:40
¿Eh? Bueno, pues 01:00:40
Las anotaciones están bien 01:00:54
El repositorio está bien 01:00:57
A falta de que no tiene ningún método así chulo 01:00:59
Ya lo incorporaremos 01:01:01
Luego lo incorporamos 01:01:03
Ay, a ver 01:01:04
Que tengo que dejar, esto 01:01:07
Pero no vamos a hacerlo con un main 01:01:08
Entonces vamos a hacerlo con un microservicio 01:01:11
Pues que necesitamos 01:01:13
El controller 01:01:17
El controller es el que recoge la url 01:01:19
De petición 01:01:22
De ese microservicio 01:01:23
Hace la llamada al servicio 01:01:25
Y me devuelve el json correspondiente 01:01:28
de respuesta o ejecuta 01:01:30
lo que toque en la base de datos 01:01:32
depende de si es una consulta o es una 01:01:33
modificación de la base de datos 01:01:36
el microservicio, el API REST 01:01:37
me puede servir tanto para recuperar datos 01:01:39
como para modificar la base de datos 01:01:42
¿vale? ¿ya lo puedo quitar? 01:01:43
bueno, pues entonces 01:01:47
nos vamos a hacer nuestro supercontroller 01:01:49
¿vale? 01:01:52
a ver, voy a 01:01:57
cerrar que tengo aquí con mucha cosa abierta 01:01:59
pues ala 01:02:03
Paquete, paquetillo 01:02:03
App, otra vez me falta 01:02:06
Vale, controller 01:02:18
Puede haber todos los que a mí me dé la gana 01:02:37
Cada uno puede estar asociado 01:02:39
A un tipo de peticiones relacionadas con alumnos 01:02:41
Con matrículas, con lo que sea 01:02:43
Y cada controlador estará 01:02:45
Colgando, pues de una a una URL 01:02:47
¿Vale? Bueno, pues entonces 01:02:49
Empezamos a configurarlo 01:02:51
¿Vale? 01:02:53
Primero, vamos a avisar a Spring 01:02:55
A Spring Web, en este caso 01:02:57
Hasta aquí Spring Web no lo hemos tocado 01:02:59
Solo hemos tocado la dependencia 01:03:01
De Spring Data JPA 01:03:04
Y son las únicas que hemos tocado 01:03:05
Aquí ya 01:03:08
Todas las anotaciones que vienen ahora 01:03:09
Son ya de la parte 01:03:12
De Spring Web modelo vista controlador 01:03:14
Bueno, pues vamos a decirle 01:03:16
Oye tú, Spring Web, tú que sabes 01:03:18
Configurar todo esto y sabes desplegar 01:03:19
El Tomcat y sabes hacerlo todo 01:03:21
Esto va a ser un controlador 01:03:23
De tipo REST 01:03:26
¿Vale? Con todo lo que eso implica 01:03:27
¿Qué implica todo eso? 01:03:31
Pues que se va a comunicar con JSON 01:03:34
Tanto en las subidas de datos 01:03:35
Como en lo que él te envía 01:03:37
Un montón de cosas de arquitectura interna 01:03:39
¿Vale? 01:03:41
¿Qué diferencia hay si lo marco? 01:03:44
¿Perdón? 01:03:47
¿Qué diferencia hay si lo marco controller? 01:03:47
Porque controller 01:03:51
O sea, es un controlador general 01:03:52
No es un controlador específico de web 01:03:55
¿Vale? 01:03:57
Entonces, no habilita por debajo todo el Jackson para el Jason, todo. Entonces, Controller como que no tiene una información muy específica, pero REST Controller ya sí. Vale, entonces, hay que avisar de dónde, si es un REST Controller, o sea, un Controller no le pondrías aquí abajo la anotación de GetMapping ni de nada de eso. 01:03:59
ResController ya implica 01:04:19
Oye tú, Controller, tú vas a estar a la escucha 01:04:23
Enganchado 01:04:25
En un Tomcat que está escuchando peticiones 01:04:27
Entonces, tengo que decirte 01:04:29
La URL raíz 01:04:32
De la cual tú vas a colgar 01:04:34
Pues como te digo 01:04:35
La URL raíz de la que tú vas a colgar 01:04:37
Con la anotación request mapping 01:04:39
¿Vale? Y con la anotación request mapping 01:04:41
Le decimos 01:04:44
Pues venga 01:04:45
Tú vas a colgar 01:04:46
a partir de la ruta base 01:04:49
de mi proyecto 01:04:52
vas a colgar, por ejemplo, de alumnos 01:04:52
¿vale? vas a colgar de ahí 01:04:55
entonces, ¿eso qué significa? 01:04:57
que los métodos 01:05:00
que ahora se pongan aquí debajo 01:05:02
los métodos que ahora se pongan 01:05:03
¿vale? pues se van a invocar 01:05:04
cuando yo llame a esta ruta 01:05:07
si es que ese método no tiene nada 01:05:10
añadido, o a esta ruta 01:05:11
con catenada con la que yo le ponga 01:05:13
luego 01:05:15
Bueno, la que tú quieras 01:05:16
¿No te gusta alumno? Pues alumno 01:05:20
A ver, como es un 01:05:23
Como es un microservicio relacionado 01:05:24
Con gestionar alumnos 01:05:27
Pues lo he llamado alumnos 01:05:29
Es una 01:05:30
No, es una ruta 01:05:32
Entonces, vale 01:05:34
Puedes poner aquí la ruta que quieras 01:05:36
La que tú te vayas a entender con ella 01:05:38
Pues es muy típico también poner 01:05:39
API 01:05:41
Porque esto es una API REST 01:05:43
API alumnos, por ejemplo 01:05:45
Porque es una API REST, pues yo que sé 01:05:47
La que quieras poner, la que cuelgue tu servicio 01:05:49
Vale 01:05:51
Vale, pues entonces 01:05:51
El controlador, este es como si fuera nuestro main 01:05:54
Este es nuestro main 01:05:57
Entonces necesita el servicio, ¿verdad? 01:05:59
Entonces, este sí que sí 01:06:01
Necesita el servicio 01:06:03
Que se llama 01:06:04
Alumnoservice 01:06:06
Va a necesitar alumnoservice 01:06:08
Y este se lo vamos a inyectar por 01:06:17
Constructor, lógicamente 01:06:19
alumno 01:06:21
y ahora ya vienen 01:06:33
los métodos 01:06:52
los métodos que recogen 01:06:54
lo que este microservicio 01:06:56
puede hacer, las pequeñas partes 01:06:59
que puede hacer 01:07:00
lo de llamarle microservicio 01:07:01
es porque se supone que hace cosas atómicas 01:07:03
pequeñitas, por eso os dijeron 01:07:05
bueno, pues ahora mismo es que solamente 01:07:07
tenemos un método de servicio 01:07:10
solo tenemos un método de servicio 01:07:11
pues entonces vamos a hacer 01:07:13
Un método de controlador 01:07:15
Para llamar a ese único método de servicio 01:07:17
Que tenemos 01:07:19
Pues venga, vamos a 01:07:20
A ese método de controlador 01:07:23
Public 01:07:25
Pues le llamo como me dé la gana 01:07:27
A este método de controlador 01:07:29
GetAlumnoById 01:07:32
Como me dé a mí la gana llamarlo 01:07:35
¿Vale? Ahora completamos todo 01:07:37
Lo que falta 01:07:39
Este método es un método de controlador 01:07:40
Que es el que va a llamar al servicio 01:07:43
Para devolver al alumno y todo eso 01:07:44
¿Vale? 01:07:47
Entonces, este de aquí 01:07:48
Me va a hacer algo como esto 01:07:51
retomService.getAlumno 01:07:55
Vale 01:08:01
Pero aquí me faltan cosas 01:08:03
Por configurar, lógicamente 01:08:05
La idea es que este método 01:08:06
De controlador me haga esto 01:08:09
Primera cosa que me falta por 01:08:10
Configurar 01:08:12
Ah, bueno, sí, vale 01:08:14
Es un error de sintaxis 01:08:16
Vale 01:08:19
Sí, sí, sí 01:08:20
No, hombre, no 01:08:22
Hay muchos más conocimientos ahí 01:08:27
Vale, cosas que nos faltan por configurar 01:08:29
Primera, todos los métodos 01:08:33
Del controlador 01:08:35
Todos se despiertan como 01:08:35
Resultado de una petición HTTP 01:08:38
Todos, vale 01:08:40
Las peticiones HTTP pueden ser de dos tipos 01:08:42
¿Verdad? Get y Post 01:08:45
Primera cosa que tenemos que configurar 01:08:46
Oye, tú, método de controlador 01:08:49
¿Te toca despertarte cuando la petición 01:08:51
Sea get o cuando la 01:08:53
Petición de la HTTP sea post? 01:08:55
Vale, pues eso 01:08:58
En este caso, como este método de controlador 01:08:59
Es para hacer una consulta 01:09:01
Queremos que se despierte a una petición get 01:09:02
¿Vale? Pues entonces le ponemos 01:09:05
Aquí la anotación 01:09:07
GetMapping 01:09:08
¿Vale? 01:09:10
Le ponemos anotación GetMapping 01:09:12
Ahora, si yo dejo el GetMapping 01:09:14
aquí sin más 01:09:16
sin más 01:09:18
este método se despierta 01:09:19
cuando yo invoque esto 01:09:22
con la ruta base, cuando invoque 01:09:24
la ruta base es cuando se despierta este método 01:09:26
si yo pongo esto así sin más 01:09:28
pero en este caso no tiene sentido 01:09:30
porque yo a este método le quiero pasar un parámetro 01:09:32
¿vale? tendría sentido 01:09:34
si este fuera getAlumnos 01:09:36
y yo tengo un método service 01:09:38
de getAlumnos al que llamo 01:09:40
findAll 01:09:42
pues ahí sí 01:09:43
Y entonces, poniendo esto, pero en este caso yo quiero una id, con lo cual vamos a concatenarlo con algo más. Y ese algo más con la que vamos a concatenar alumnos debería ser el parámetro, el id del alumno, debería ser el parámetro. 01:09:45
Entonces, para indicar que eso no es ruta tal cual, no es ruta tal cual, sino que es parámetro, no, ya ves, aquí, aquí ya ves. Vale, entonces esto significa, tú, GetMapping, despiértate cuando te llegue una petición del tipo, la base donde está desplegada la aplicación, API alumnos y después barra alguna cosita. 01:09:59
Y esa cosita va a ser tu parámetro 01:10:22
¿Vale? Pero hay que indicarle aquí 01:10:25
Hay que indicarle aquí 01:10:27
Que este tiene que coger 01:10:29
Una variable de la ruta 01:10:32
Hay que decirle, oye tú 01:10:33
Que tú te vas a llenar de una variable de la ruta 01:10:35
Pues entonces eso se le indica así 01:10:37
Claro, entonces 01:10:39
Path variable significa 01:10:51
Este parámetro tiene que cogerse 01:10:52
De la ruta 01:10:56
De la ur, le tiene que cogerse de ahí 01:10:58
Entonces pues nada 01:11:01
Él tranquilamente dice, ah vale, vale, vale 01:11:03
Me voy a la ruta y lo cojo de aquí 01:11:05
Busco una variable de la ruta 01:11:08
Que esté entre llaves 01:11:10
¿Vale? 01:11:10
Se pueden hacer más de uno 01:11:15
Tú podrías ahí concatenar 01:11:17
Quiero coger por alumnoide 01:11:19
Y además recuperar 01:11:21
Por número de matrícula o por lo que fuera 01:11:23
Por cualquier otro parámetro que quisieras poner 01:11:25
Pues esto es válido 01:11:28
Perfectamente 01:11:29
Y aquí lo separas por coma 01:11:30
Pad variable, string 01:11:32
O lo que sea este jj 01:11:35
Por el nombrecito 01:11:36
Por el nombrecito 01:11:39
¿Vale? 01:11:40
Entonces puedes poner lo que quieras 01:11:43
Entonces 01:11:45
El problema 01:11:48
Un problema sutil 01:11:49
Es que la url 01:11:51
No distingue entre string, int 01:11:53
Para ella son todo cadenas 01:11:56
Entonces 01:11:57
Tú no puedes hacer dos get mapping 01:11:59
Que tengan 01:12:02
Dos variables aquí 01:12:04
Y decir, ah, son distintas 01:12:06
Porque una va a ser un número y otra un string 01:12:07
Ya, pero eso no se entera uno hasta aquí 01:12:09
Antes no te enteras 01:12:11
Entonces habría una confusión 01:12:13
Entonces, que tú quieres dos get mapping 01:12:15
Pasándole dos variables consecutivas 01:12:18
Pues inserta alguna cosita entre medias 01:12:20
Algo que cambie la ruta 01:12:22
¿No? Por ejemplo, pues inserta aquí cualquier cosa 01:12:23
Y matrícula 01:12:26
no sé qué, entonces 01:12:28
ya esta sería diferente 01:12:30
de la otra, ¿vale? me refiero 01:12:32
que no puede haber dos rutas 01:12:34
equivalentes, entonces 01:12:36
claro, o sea, lo que yo quiero decir es que 01:12:40
si yo hago otro método, porque me apetece a mí 01:12:48
¿vale? este método me devuelve a través de un 01:12:50
int y de otro int, algo 01:12:52
y ahora quiero hacer un método que me 01:12:54
devuelva a partir de un int y un 01:12:56
string, otra cosa, pues eso es 01:12:58
ambiguo, porque para la URL 01:13:00
no hay int, no hay string, ni hay nada. 01:13:01
Entonces, no puedes hacer dos getMapping 01:13:04
con dos variables así, 01:13:06
porque no se va a distinguir, aunque tú sepas 01:13:08
internamente que esta va a nutrir 01:13:10
un id, esta va a nutrir un string, 01:13:12
¿vale? Entonces, pues cambia 01:13:15
la ruta, cambia la ruta, pones aquí 01:13:16
otra cosa, lo que sea, para que las rutas sean 01:13:18
funcionalmente distintas. 01:13:19
Para que sean funcionalmente distintas, ¿vale? 01:13:22
Bueno, esto lo has respondido a tu pregunta 01:13:24
y se pueden poner varios. Pues sí, se pueden poner 01:13:26
todos los que uno quiera. 01:13:28
En nuestro caso 01:13:29
Recuperar por id 01:13:30
Y ya está 01:13:32
Ya está 01:13:37
¿Vale? 01:13:38
Ya está 01:13:40
Entonces todo esto 01:13:40
Tiene por debajo 01:13:41
La llamada al servlet 01:13:43
¿La llamada a qué? 01:13:45
Spring tiene por debajo Jackson 01:13:48
Que ya sabemos cómo funciona 01:13:49
Jackson pues te construye 01:13:50
A partir de una entidad 01:13:52
Te construye un JSON 01:13:54
Y viceversa 01:13:55
¿Vale? 01:13:56
Mediante anotaciones o lo que sea 01:13:57
Y si no hay anotaciones 01:13:58
Pues te lo construye 01:14:00
con los nombres por defecto 01:14:01
pues Spring tiene por debajo el Jackson 01:14:03
que lo hemos visto en las dependencias 01:14:05
que coge este alumno 01:14:06
lo mapea a JSON 01:14:08
y te lo manda, y ya está 01:14:10
¿vale? por eso es un microservicio 01:14:12
porque no está pensado para que alguien 01:14:15
lo vea en el navegador, nosotros lo vamos a ver en el navegador 01:14:17
sino está pensado para que 01:14:19
tú llames a esto desde 01:14:20
otra aplicación, cojas ese JSON 01:14:23
con ese JSON te saques la información que te dé la gana 01:14:24
lo que sea, pero eso ya es otro 01:14:27
problema, vale, es llamar 01:14:29
a esto desde un cliente, que podemos hacerlo 01:14:31
también y ya está, pero bueno, nos es más cómodo 01:14:33
llamarlo desde el navegador, pues venga 01:14:35
yo creo que no se me ha 01:14:37
olvidado nada, veréis, si me he olvidado algo, pues casi 01:14:39
mejor, porque así 01:14:41
no salen errores 01:14:42
vale, pues entonces 01:14:44
ahora que ya tenemos 01:14:46
todo 01:14:48
el controller, el no sé qué 01:14:50
vamos a lanzar la aplicación 01:14:52
esto se tiene que desplegar 01:14:54
en un Tomcat 01:14:57
pero bueno, tenemos la suerte 01:14:57
de que para hacer las pruebas 01:15:00
si nosotros lanzamos 01:15:02
la aplicación Spring Boot aquí desde el Eclipse 01:15:04
o desde el IntelliJ 01:15:06
pues automáticamente 01:15:07
se lanza un Tomcat 01:15:10
en el cual se despliega la aplicación 01:15:12
y ya está, y yo la puedo invocar 01:15:14
desde mi navegador 01:15:16
que yo ya no estoy en fase de pruebas 01:15:18
pues lógicamente el Tomcat que lanza el Eclipse 01:15:22
y que se cierra con el Eclipse que está embebido 01:15:24
no me vale, pero es que entonces 01:15:26
que haríamos, cogemos esta aplicación 01:15:27
tal cual, la empaquetamos en war 01:15:29
en el formato war 01:15:31
y ahora ya nos vamos con ese war 01:15:33
al servidor Tomcat que sea 01:15:36
y ya está, metemos el war en el Tomcat, pum 01:15:37
se despliega y ya puede uno 01:15:39
llamar a ese 01:15:41
Tomcat, pero bueno, como estamos en pruebas 01:15:43
vamos a lanzarlo desde aquí 01:15:45
vale, pues venga, lanzamos 01:15:46
esto, a ver 01:15:49
cuantos errores nos salen 01:15:54
webserver 01:15:56
was already in use 01:15:59
Yo porque lo tengo en use 01:16:01
Ah, vale, vale, vale 01:16:04
Que no había parado yo, vale, vale 01:16:09
El controller 01:16:10
Es que ya está completamente configurado 01:16:15
El controller ya automáticamente despliega 01:16:16
Tu aplicación web en esta url 01:16:19
Vale, es que aquí no hay página web, no hay nada 01:16:21
Entonces vamos a volver a intentarlo 01:16:24
Venga 01:16:28
Ah, bueno, me ha hecho el main 01:16:29
Pero el main se me ha olvidado quitarlo 01:16:38
Entonces, no me ha dado errores 01:16:40
Esto en principio 01:16:43
A ver, en el main es que ya lo puedo quitar 01:16:44
Si quiero, ya no lo, era para hacer la prueba 01:16:49
O sea, es que me refiero que me lo ha hecho 01:16:50
Porque se me ha olvidado quitarlo 01:16:52
Esto, para la próxima lo quito 01:16:53
Entonces, ahora lo que, esto se supone que está lanzado en un Tomcat 01:16:55
Vamos a probarlo 01:16:59
Me voy yo aquí 01:17:00
vale, como este es el Tomcat 01:17:02
interno, la aplicación 01:17:05
se me ha desplegado aquí 01:17:08
directamente en el localhost, porque estoy en las pruebas 01:17:09
del Eclipse 01:17:12
voy tranquilo 01:17:12
pero en una situación real 01:17:14
uno cuando coge esta aplicación 01:17:17
la empaqueta en un guard y la despliega 01:17:20
en ese guard, pues entonces 01:17:22
ya la ruta raíz de su aplicación 01:17:24
será la IP del servidor 01:17:25
con el nombre de esa 01:17:28
aplicación, aquí el nombre 01:17:30
de la aplicación no me hace falta 01:17:31
porque estoy en el Tomcat interno que se ha 01:17:33
desplegado específicamente 01:17:35
para esta aplicación, por eso aquí no lo pongo 01:17:38
vale, entonces 01:17:39
aquí lógicamente no tengo nada escuchando aquí 01:17:41
normal que me dé un error 01:17:43
pues venga, vamos a llamar 01:17:44
a mi stack 01:17:47
API alumnos 1 01:17:49
vale 01:17:50
madre del amor hermoso 01:17:52
porque la matrícula tiene un alumno 01:17:55
que el alumno tiene matrícula, que la matrícula tiene un alumno 01:17:59
Qué bonito, ¿verdad? 01:18:01
Fijaos qué cantidad de llaves juntas 01:18:05
Sí, mi pregunta es por qué para 01:18:07
No sé por qué para 01:18:10
Porque la recursión es infinita 01:18:11
Pero para 01:18:13
Vale, en cualquier caso esto no nos gusta 01:18:14
No nos gusta, nada 01:18:18
Claro, mola pero nos gusta 01:18:21
Antes de hacer el cambio que deberíamos hacer 01:18:25
Para esto 01:18:28
Vamos a ponerle en el properties 01:18:28
Porque el JSON de salida así formateado no vemos nada 01:18:31
Hay una propiedad 01:18:33
Que le puedes poner en el properties 01:18:35
Para que te formate 01:18:36
Que creo que antes este me lo ha dado 01:18:38
Como que la tenía puesta en el otro lado 01:18:40
Ah, la tenía puesta en 01:18:44
Y este no me lo ha ofrecido 01:18:47
No me lo ha ofrecido 01:18:48
Bueno, pero yo la tenía puesta en mi otro proyecto 01:18:50
Vale, la tenía puesta en mi otro proyecto 01:18:52
Pero me salía muy feo todo 01:18:56
Esta 01:18:57
Esta es la que yo quiero 01:18:58
Para que salga bonito en el navegador 01:19:03
Que si no 01:19:05
Sale más feo que nada 01:19:05
Vale, para que indente el JSON 01:19:07
En el navegador 01:19:13
Para que salga intentado 01:19:15
Si esto va a una máquina, da igual 01:19:16
Pues va a una máquina 01:19:21
La máquina parsea 01:19:23
Los saltos 01:19:24
Pero para nuestras pruebas de bruno en el navegador 01:19:29
Vale, voy a volver a relanzarlo 01:19:31
Pues buf, buf, buf 01:19:44
Así queda todavía más bonito 01:20:00
Se ha llegado hasta saltar 01:20:02
Pam, pam, pam, pam 01:20:03
Pam, pam, pam, pam 01:20:04
Así es que mueve más 01:20:06
Vale, pues no, obviamente no 01:20:08
No queremos esto 01:20:10
Entonces 01:20:12
Soluciones que tenemos 01:20:14
Efectivamente, solución 01:20:16
Fea, horrible, muy mala 01:20:18
Caca, la tuya 01:20:20
Efectivamente, pero muy natural 01:20:22
Que es, ¿cuál es el problema? 01:20:25
El problema es que matrícula me ha devuelto el alumno. 01:20:26
¿Alumno tiene matrícula? 01:20:31
Me voy hasta el infinito. 01:20:33
Bueno, como recordamos de JSON que había anotaciones 01:20:36
para configurar el parseo de entidad a JSON, 01:20:39
pues creemos recordar que había una que era JSON ignore. 01:20:43
Ignore el alumno a la hora de mapear en JSON la matrícula. 01:20:53
Esto es independiente de lo anterior. 01:20:58
¿Vale? 01:21:01
Entonces, y lo mismo, 01:21:02
podríamos, esto no deja de ser 01:21:05
una entidad que se va a mapear en un JSON. 01:21:07
Podríamos aquí cambiar los 01:21:09
campos, que no me gusta que ponga asignatura, 01:21:10
quiero que ponga nombre, pues JSON 01:21:13
property nombre, aquí uno puede 01:21:15
mezclar actuaciones Jackson con actuaciones JPA, 01:21:17
no hay ningún problema. ¿Vale? 01:21:19
Entonces, 01:21:21
que en el mapeo JSON, ignórame 01:21:22
al alumno en el mapeo JSON, por favor. 01:21:24
Pero entonces 01:21:34
tengo que añadir un campo aquí y cambio 01:21:35
mi lógica de negocio y eso sí que no 01:21:36
¿vale? 01:21:39
pero por ahí van los tiros del segundo 01:21:40
arreglo, en principio, esa es la idea 01:21:43
entonces 01:21:45
vamos a 01:21:46
la hemos relanzado 01:21:49
y ahora 01:21:52
hombre 01:21:57
muy bien 01:21:58
¿vale? 01:22:01
ya me sale toda la información del alumno 01:22:03
con sus matrículas, pero de cada 01:22:05
matrícula no ha vuelto 01:22:08
mapear el alumno otra vez, así hasta 01:22:10
el infinito, bla bla bla 01:22:11
vale, como veis 01:22:13
porque uno aquí podría hacerse esa 01:22:21
pregunta, que seguro que os está rondando la cabeza 01:22:23
pero a ver 01:22:25
esto era lazy 01:22:27
claro, o sea 01:22:28
esto era lazy, entonces cuando yo devuelvo 01:22:34
el alumno, lo devuelvo el alumno en 01:22:37
lazy, con lo cual cuando él mapea 01:22:39
no tiene eso, pero es que el mapeo se hace 01:22:41
antes, vale 01:22:43
entonces eso no afecta 01:22:45
el lazy, el jason va a aparecer 01:22:47
bueno, pues que ocurre 01:22:48
que vale, que esto lo podríamos dejar así 01:22:51
pero 01:22:53
ostras 01:22:55
es un poco feo 01:22:56
¿vale? porque ya es un parchecillo 01:22:59
ahí, a lo mejor 01:23:01
mi aplicación hace más cosas con 01:23:03
jason, y jolines yo no quiero 01:23:05
ignorar este campo todo el rato, porque a lo mejor 01:23:07
me llevo la matrícula con su alumno 01:23:09
y no quiero que ignore el campo alumno en otros 01:23:11
contextos, entonces estoy 01:23:13
poniendo algo 01:23:15
que a lo mejor en otras situaciones de mi aplicación 01:23:17
me puede venir mal. 01:23:21
Eso por un lado. 01:23:22
Pero aunque eso no sea lo que ocurre, 01:23:23
que lo normal es que no sea lo que ocurra, 01:23:25
estoy ensuciando el modelo. 01:23:27
Entonces, el modelo tiene que ser una cosa muy limpia 01:23:32
que solamente tenga información relativa a la base de datos 01:23:35
o lo que es lo mismo, JPA, 01:23:40
y nada de meterle mierdas relacionadas con mi aplicación. 01:23:42
Y esto lo es. 01:23:45
Porque esto es una mierdecilla 01:23:46
Que yo he metido porque el Jason me sale anidado 01:23:48
Etcétera, etcétera 01:23:51
Entonces, modelo tiene que ser como una especie 01:23:52
De Dios, que no se le toca 01:23:55
¿Vale? En principio 01:23:56
Luego 01:23:58
Si no me gusta esto 01:24:00
Que no es que te esté regañando 01:24:02
Si es la opción natural 01:24:04
Lo que estoy diciendo es un poco, pues bueno, los principios básicos 01:24:05
Con lo cual 01:24:08
¿Cuál es la solución habitual? 01:24:09
Es decir, perdona, es que mi problema ha sido 01:24:12
Que yo ya de partida he hecho una cosa 01:24:14
muy, muy, muy, muy fea. 01:24:16
¿Qué es? 01:24:19
No. 01:24:20
Poner objetos 01:24:23
del modelo ahí en el controlador. 01:24:24
Tú, controlador, devuélveme a alumno. 01:24:26
Pero alumno tiene 01:24:28
todo lo de la base de datos, entre ellos 01:24:30
ID. ID es un valor 01:24:32
interno. 01:24:34
Justo. Yo no quiero que ID 01:24:36
vaya a lo mejor, que necesidad de que vaya navegando 01:24:38
por ahí. Entonces, 01:24:40
lo que el controlador me devuelve 01:24:42
y lo que yo al controlador le doy 01:24:44
tiene que ser específicamente 01:24:47
lo que quiero para esa consulta. 01:24:49
Pues para eso me hago mi DTO. 01:24:52
Que tengo 20 consultas 01:24:54
relacionadas con alumno 01:24:56
y cada uno me saca una distinta. 01:24:57
Pues 20 DTOs distintos. 01:24:59
Y no pasa nada por tener un paquete de DTOs 01:25:01
con 20 DTOs. 01:25:03
Cada uno para su consulta. 01:25:04
Pues entonces, es que yo, por tanto, 01:25:06
no tendría que haber hecho esto así. 01:25:08
Yo tendría que haber hecho 01:25:11
Esto 01:25:12
Lo voy a 01:25:13
Exacto 01:25:15
Tendría que haber hecho esto 01:25:17
Tú, devuélveme un objeto 01:25:19
DTO 01:25:22
Vale, no me devuelvas 01:25:23
Vale 01:25:28
Vamos a hacer una cosa 01:25:29
Vamos a parar un momentito 01:25:32
Porque llevamos un montón de rato seguido 01:25:33
Y aparte hay que 01:25:36
Ver qué pasa con Javi 01:25:37
Materias:
Programación
Niveles educativos:
▼ Mostrar / ocultar niveles
  • Formación Profesional
    • Ciclo formativo de grado superior
      • Segundo Curso
Subido por:
Raquel G.
Licencia:
Todos los derechos reservados
Visualizaciones:
1
Fecha:
10 de febrero de 2026 - 13:56
Visibilidad:
Clave
Centro:
IES ROSA CHACEL
Duración:
1h′ 25′ 40″
Relación de aspecto:
1.78:1
Resolución:
1920x1080 píxeles
Tamaño:
365.61 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid