En esta página:
Demo Github
Ha sido un viaje largo e interminable, después de más de un año que retomo este tutorial, te pido disculpas por la demora, hubo retos y contratiempos que hicieron posible el no terminar este tutorial. Pero al final valdrá la pena la espera y es que en esta última parte veremos el proyecto en acción y te compartiré el código fuente del proyecto. Spring Framework cuenta con una nueva versión, pero ya estoy trabajando en ello, prueba de ello es la creación del tutorial: Como Crear un Proyecto con Spring Boot en donde hago uso de la versión 6 de Spring Framework, mediante Spring Boot, si te parece confuso lo que dije, te recomiend leer el post: Cual es la diferencia entre Spring (Framework) y Spring Boot. Asimismo se vienen nuevos tutoriales con la nueva versión de Spring Framework. En esta 5ta y última parte terminaremos el tutorial Como crear un CRUD con Spring Framework, vamos con ello.
Partes
Antes de continuar con este Post, te invito a leer los siguientes artículos:
- Que es Spring Framework y Otros Detalles
- 5 Consejos para escribir Controladores Spring MVC
- Como funciona la anotación @Value en Spring
- Cual es la diferencia entre Spring (Framework) y Spring Boot
- Como Crear Nuestra Primera Aplicación Básica con Spring Framework – Parte 1
- Puedes leer más en la categoría Spring
Asimismo, te invito a escuchar el Podcast: “Consejos Para Tener Más Tiempo Para Programar” y “ChatGPT ¿ Dejará sin empleo a los Desarrolladores ?” (Anchor Podcast):
Spotify: | Sound Cloud: | Apple Podcasts | Anchor Podcasts |
Bien ahora continuemos con el Post: Como crear un CRUD con Spring Framework 5.2.13 y Bootstrap 4.6 – Parte 5 (Final).
Vistas
Para las vistas usaré el framework Bootstrap y el motor de plantillas Thymeleaf, de esta manera solo me enfoco en la logica del proyecto del lado Backend. Para las vistas crearé 4 archivos HTML, estos son: actualizar.html, crear.html, index.html y leer.html. Estos archivos los creo en un directorio llamado /templates, si no tienes este directorio, crealo manualmente. El directorio /templates se ubica en sistemacrud > src > main > resources > templates
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/sistemacrud ├── /.mvn ├── /src ├── /main ├── /java ├── /resources ├── /templates // En este directorio creo los archivos HTML ├── actualizar.html ├── crear.html ├── error.html // (Este archivo es opcional ) ├── index.html.html ├── leer.html ├── .gitignore ├── HELP.md ├── mvnw ├── mvnw.cmd ├── porn.xml |
A cada uno de los archivos HTML les instancio el archivo CSS y JavaScript de Bootstrap 4.6, primero el CSS lo instancio entre las etiquetas <head></head>:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>Como Crear un CRUD con Spring Framework 5.2.13 y Bootstrap 4.6</title> <!-- Archivo CSS de Bootstrap --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <link rel="stylesheet" type="text/css" href="https://nubecolectiva.com/blog/tutos/demos/enc.css"> </head> |
Y el archivo JavaScript lo instancio antes de la etiqueta de cierre </body>:
1 2 3 4 5 6 7 |
<!-- Archivo JS de Bootstrap --> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> </body> </html> |
Ahora pasemos a crear las vistas para cada tarea del sistema CRUD.
Vista Principal
Esta vista tendrá una tabla HTML en donde se listarán todos los registros o datos que serán llamados desde la base de datos. Cada registro tendrá 3 botones al lado derecho para realizar las tareas Leer, Editar y Eliminar. Arriba de la tabla colocaré un botón para crear un nuevo registro, este botón será Crear.
Para esta vista usaré el archivo index.html, lo abro y dentro de el, agrego lo siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<!-- Botón para crear un nuevo registro --> <a th:href="@{/crear}" class="btn btn-primary mb-3">Crear</a> <!-- Mostramos el Mensaje en la Vista Principal --> <div class="alert alert-primary" role="alert" th:text="${success}" th:if="${success}"></div> <!-- Tabla con los datos --> <div class="table-responsive text-center"> <table class="table"> <thead class="table-dark"> <tr> <td>Nombre</td> <td>Precio</td> <td>Stock</td> <td>Imagen</td> <td>Acciones</td> </tr> </thead> <tbody> <tr th:each="postre:${postres}"> <td th:text="${postre.nombre}">Nombre</td> <td th:text="${postre.precio}">Precio</td> <td th:text="${postre.stock}">Stock</td> <td> <img src="/uploads/+${postre.img}" th:src="@{/uploads/}+${postre.img}" class="img-fluid" alt="${postre.img}" width="70px"> </td> <td> <a th:href="@{/leer/}+${postre.id}" class="btn btn-dark">Leer</a> <a th:href="@{/actualizar/}+${postre.id}" class="btn btn-warning">Editar</a> <a onclick="return confirmarEliminar()" th:href="@{/eliminar/}+${postre.id}" class="btn btn-danger">Eliminar</a> </td> </tr> </tbody> </table> </div> |
En el código anterior, dentro del cuerpo de la tabla HTML estoy haciendo uso de th:each de Thymeleaf que es un tipo de for para recorrer y mostrar todos los datos en la tabla.
Thymeleaf es un moderno motor de plantillas Java del lado del servidor para entornos web y es muy usado en Spring Framework. Más adelante te compartiré mi archivo pom.xml con todas las dependencias que he instalado para este proyecto, también lo podrás encontrar en el repositorio GitHub de este proyecto.
Si voy al navegador, debería de ver la vista principal con la tabla y los demás elementos, sin problemas:
Ahora pasemos a crear la vista para leer un registro.
Leer (Read)
Para esta vista usaré el archivo leer.html, lo abro y le agrego lo siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<div class="row"> <div class="col-md-12"> <span class="font-weight-bold">Nombre:</span> <p class="mb-3" th:text="${postres.isEmpty()} ? 'none' : ${postres.get().Nombre}"></p> <span class="font-weight-bold">Precio:</span> <p class="mb-3" th:text="${postres.isEmpty()} ? 'none' : ${postres.get().Precio}"></p> <span class="font-weight-bold">Stock:</span> <p class="mb-3" th:text="${postres.isEmpty()} ? 'none' : ${postres.get().Stock}"></p> <span class="font-weight-bold">Imagen:</span> <br> <img width="25%" class="img-fluid mb-3" th:src="@{/../../uploads/__${postres.isEmpty()} ? 'none' : ${postres.get().Imagen}__}"> <br> <button type="button" class="btn btn-primary" onclick="window.history.back();">Cancelar</button> </div> </div> |
En el código anterior estoy imprimiendo los datos de un solo registro por su id, este lo obtenemos desde el controlador (Controlador.java) de nuestro proyecto. Si vamos al navegador podemos ver la vista con los datos de un registro único:
Ahora pasemos a la vista para actualizar un registro.
Actualizar (Update)
Para esta vista usaré el archivo actualizar.html, lo abro y le agrego lo siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<div class="row"> <div class="col-md-12"> <h1 style="font-size: 28px;" class="mb-4 text-center">Como crear un CRUD con Spring Framework 5.2.13 y Bootstrap 4.6 </h1> <form th:action="@{'/update/' + ${id}}" th:object=${postres} method="POST" enctype="multipart/form-data"> <div class="card"> <div class="card-header"> <h3>Actualizar</h3> </div> <div class="card-body"> <div class="form-group"> <label class="negrita2">Nombre</label> <input type="text" th:field="*{nombre}" class="form-control" required> </div> <div class="form-group"> <label class="negrita2">Precio</label> <input type="text" th:field="*{precio}" class="form-control" required> </div> <div class="form-group"> <label class="negrita2">Stock</label> <input type="text" th:field="*{stock}" class="form-control" required> </div> <div class="form-group"> <label class="negrita2">Imagen</label> <input type="file" id="img" name="img" class="form-control"> </div> <div class="form-group"> <label class="negrita2">Imagen Actual</label> <br> <img width="25%" class="img-fluid mb-3" th:src="@{/../../uploads/__${postres.isEmpty()} ? 'none' : ${postres.get().Imagen}__}"> </div> </div> <div class="card-footer"> <input type="submit" value="Guardar" class="btn btn-sucess"> <button type="button" class="btn btn-primary" onclick="window.history.back();">Cancelar</button> </div> </div> </form> </div> </div> |
En el código anterior he colocado un formulario HTML y en cada campo coloco los datos de un registro que se podrán editar. Si voy al navegador, puedo ver la vista para actualizar un registro con un formulario determinado:
Ahora pasemos a la vista eliminar, que no va ser exactamente una vista, sino que la manejaremos de forma práctica.
Eliminar (Delete)
Esta no será exactamente una vista, si tu deseas la puedes crear, no hay problema. En la vista principal pudiste ver que teniamos una tabla con todos los registros y al lado derecho cada uno tiene 3 botones, uno de ellos es Eliminar, cuando el usuario presiona ese botón le aparecerá una ventana de alerta para confirmar o no la eliminación del registro. El botón Eliminar llama al método confirmarEliminar() al ser presionado:
1 2 3 4 |
<!-- Botón para eliminar un registro --> <a onclick="return confirmarEliminar()" th:href="@{/eliminar/}+${postre.id}" class="btn btn-danger">Eliminar</a> |
El siguiente es el método JavaScript, el cual lo he colocado antes de cerrar la etiqueta </body>:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<script type="text/javascript"> function confirmarEliminar() { var x = confirm("Estas seguro de Eliminar?"); if (x) return true; else return false; } </script> </body> </html> |
Entonces si vamos al navegador y presionamos el botón Eliminar de un registro, aparecerá la ventan de alerta:
Esas seria todas las vistas de nuestro sistema CRUD.
Dependencias
En mi archivo pom.xml he usado diferentes dependencias y librerías, te dejo a continuación todo el código del archivo, (También lo podrás encontrar en el repositorio de GitHub de este proyecto):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# Contenido del archivo 'pom.xml' <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.2</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.sistemacrud</groupId> <artifactId>sistemacrud</artifactId> <version>0.0.1-SNAPSHOT</version> <name>sistemacrud</name> <description>Sistema Crud</description> <properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/javax.persistence/javax.persistence-api --> <dependency> <groupId>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>2.4.0</version> <!--DEJAR EN ESTA VERSIÓN PARA QUE RECONOZCA LA LIBRERÍA org.springframework.data.repository.Repository--> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.7</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.5</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.11.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> |
Bien, hasta aquí llegamos con este tutorial, al inicio te he dejado un enlace con el código del proyecto alojado en GitHub y una Demo para que veas el proyecto en acción.
Conclusión
En este tutorial has aprendido a Como crear un CRUD con Spring Framework 5.2.13 y Bootstrap 4.6, aprender a realizar tareas CRUD, es muy importante, ya que todas las aplicaciones y el software en general, utiliza tareas CRUD, Aprender a como crear un CRUD, te servirá de mucho para crear aplicaciones más avanzadas en Spring Framework.
Nota(s)
- No olvides que debemos usar la Tecnología para hacer cosas Buenas por el Mundo.
Síguenos en nuestras Redes Sociales para que no te pierdas nuestros próximos contenidos.