20260210 API_REST_1 - Contenido educativo
Ajuste de pantallaEl ajuste de pantalla se aprecia al ver el vídeo en pantalla completa. Elige la presentación que más te guste:
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
En
00:11:54
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
00:20:26
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
Sí
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
si
00:33:25
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
Si
00:36:34
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
M
00:40:11
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
M
00:41:28
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
No
00:46:38
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
Un
01:25:26
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