Aplicación Spring Boot CRUD con Thymeleaf

1. Información general

La implementación de capas DAO que brindan funcionalidad CRUD en entidades JPA puede ser una tarea repetitiva y lenta que queremos evitar en la mayoría de los casos. Afortunadamente, Spring Boot facilita la creación de aplicaciones CRUD a través de una capa de repositorios CRUD estándar basados ​​en JPA.

En este tutorial, aprenderemos cómo desarrollar una aplicación web CRUD con Spring Boot y Thymeleaf .

2. Las dependencias de Maven

En este caso, confiaremos en spring-boot-starter-parent para una administración de dependencias simple, control de versiones y configuración de complementos. Como resultado, no necesitaremos especificar las versiones de las dependencias del proyecto en nuestro archivo pom.xml , excepto para anular la versión de Java:

 org.springframework.boot spring-boot-starter-parent 2.2.2.RELEASE    org.springframework.boot spring-boot-starter-web   org.springframework.boot spring-boot-starter-thymeleaf   org.springframework.boot spring-boot-starter-data-jpa   com.h2database h2   

3. La capa de dominio

Con todas las dependencias del proyecto ya implementadas, implementemos ahora una capa de dominio ingenua.

En aras de la simplicidad, esta capa incluirá una sola clase que será responsable de modelar las entidades de usuario :

@Entity public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; @NotBlank(message = "Name is mandatory") private String name; @NotBlank(message = "Email is mandatory") private String email; // standard constructors / setters / getters / toString }

Tengamos en cuenta que hemos anotado la clase con la anotación @Entity . Por tanto, la implementación de JPA, que es Hibernate, en este caso, podrá realizar operaciones CRUD en las entidades de dominio. Para obtener una guía introductoria a Hibernate, visite nuestro tutorial sobre Hibernate 5 con Spring.

Además, hemos restringido los campos de nombre y correo electrónico con la restricción @NotBlank . Esto implica que podemos usar Hibernate Validator para validar los campos restringidos antes de persistir o actualizar una entidad en la base de datos.

Para conocer los conceptos básicos sobre esto, consulte nuestro tutorial asociado sobre la validación de Bean.

4. La capa del repositorio

En este punto, nuestra aplicación web de muestra no hace nada. Pero eso está a punto de cambiar.

Spring Data JPA nos permite implementar repositorios basados ​​en JPA (un nombre elegante para la implementación del patrón DAO) con un mínimo de problemas .

Spring Data JPA es un componente clave de spring-boot-starter-data-jpa de Spring Boot que facilita agregar la funcionalidad CRUD a través de una poderosa capa de abstracción colocada sobre una implementación de JPA. Esta capa de abstracción nos permite acceder a la capa de persistencia sin tener que proporcionar nuestras propias implementaciones de DAO desde cero.

Para proporcionar a nuestra aplicación la funcionalidad CRUD básica en objetos de usuario , todo lo que tenemos que hacer es extender la interfaz CrudRepository :

@Repository public interface UserRepository extends CrudRepository {}

¡Y eso es! Simplemente extendiendo la interfaz CrudRepository , Spring Data JPA nos proporcionará implementaciones para los métodos CRUD del repositorio.

5. La capa de controlador

Gracias a la capa de abstracción que spring-boot-starter-data-jpa coloca sobre la implementación de JPA subyacente, podemos agregar fácilmente algunas funciones CRUD a nuestra aplicación web a través de un nivel web básico .

En nuestro caso, una sola clase de controlador será suficiente para manejar las solicitudes HTTP GET y POST y luego asignarlas a las llamadas a nuestra implementación de UserRepository .

La clase de controlador se basa en algunas de las características clave de Spring MVC. Para obtener una guía detallada sobre Spring MVC, consulte nuestro tutorial de Spring MVC.

Comencemos con los métodos showSignUpForm () y addUser () del controlador .

El primero mostrará el formulario de registro del usuario, mientras que el segundo conservará una nueva entidad en la base de datos después de validar los campos restringidos.

Si la entidad no pasa la validación, se volverá a mostrar el formulario de registro. En caso contrario, una vez guardada la entidad, la lista de entidades persistentes se actualizará en la vista correspondiente:

@Controller public class UserController { @GetMapping("/signup") public String showSignUpForm(User user) { return "add-user"; } @PostMapping("/adduser") public String addUser(@Valid User user, BindingResult result, Model model) { if (result.hasErrors()) { return "add-user"; } userRepository.save(user); return "redirect:/index"; } // additional CRUD methods }

También necesitaremos un mapeo para la URL / index :

@GetMapping("/index") public String showUserList(Model model) { model.addAttribute("users", userRepository.findAll()); return "index"; }

Dentro del UserController también tendremos el método showUpdateForm () que es responsable de obtener la entidad de usuario que coincide con el ID proporcionado de la base de datos.

Si la entidad existe, se pasará como un atributo de modelo a la vista del formulario de actualización, por lo tanto, el formulario se puede completar con los valores de los campos de nombre y correo electrónico :

@GetMapping("/edit/{id}") public String showUpdateForm(@PathVariable("id") long id, Model model) { User user = userRepository.findById(id) .orElseThrow(() -> new IllegalArgumentException("Invalid user Id:" + id)); model.addAttribute("user", user); return "update-user"; } 

Finalmente, tenemos los métodos updateUser () y deleteUser () dentro de la clase UserController .

El primero conservará la entidad actualizada en la base de datos, mientras que el último eliminará la entidad dada.

En cualquier caso, la lista de entidades persistentes se actualizará en consecuencia:

@PostMapping("/update/{id}") public String updateUser(@PathVariable("id") long id, @Valid User user, BindingResult result, Model model) { if (result.hasErrors()) { user.setId(id); return "update-user"; } userRepository.save(user); return "redirect:/index"; } @GetMapping("/delete/{id}") public String deleteUser(@PathVariable("id") long id, Model model) { User user = userRepository.findById(id) .orElseThrow(() -> new IllegalArgumentException("Invalid user Id:" + id)); userRepository.delete(user); return "redirect:/index"; }

6. La capa de vista

En este punto, hemos implementado una clase de controlador funcional que realiza operaciones CRUD en entidades de usuario . Aun así, todavía falta un componente en este esquema: la capa de vista.

En la carpeta src / main / resources / templates , necesitamos crear las plantillas HTML necesarias para mostrar el formulario de registro, el formulario de actualización y representar la lista de entidades de usuario persistentes .

Como se indicó en la introducción, usaremos Thymeleaf como motor de plantilla subyacente para analizar los archivos de plantilla.

Aquí está la sección relevante del archivo add-user.html :

 Name   Email    

Observe cómo hemos usado la expresión de URL @ {/ adduser} para especificar el atributo de acción del formulario y las expresiones de la variable $ {} para incrustar contenido dinámico en la plantilla, como los valores de los campos de nombre y correo electrónico y la validación posterior. errores .

Similar a add-user.html , así es como se ve la plantilla update-user.html :

 Name   Email    

Finalmente, tenemos el archivo index.html que muestra la lista de entidades persistentes junto con los enlaces para editar y eliminar las existentes:

No users yet!

Users

Name Email Edit Delete
Edit Delete

Add a new user

En aras de la simplicidad, las plantillas se ven bastante esqueléticas y solo brindan la funcionalidad requerida sin agregar cosméticos innecesarios.

Para dar a las plantillas un aspecto mejorado y llamativo sin dedicar demasiado tiempo a HTML / CSS, podemos usar fácilmente un kit de interfaz de usuario de Twitter Bootstrap gratuito, como Shards.

7. Ejecución de la aplicación

Finalmente, definamos el punto de entrada de la aplicación. Como la mayoría de las aplicaciones Spring Boot, podemos hacer esto con un método main () simple y antiguo :

@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }

Ahora, presionemos "Ejecutar" en nuestro IDE, luego abramos nuestro navegador y apuntemos a // localhost: 8080 .

Si la compilación se ha compilado correctamente , deberíamos ver un panel de usuario de CRUD básico con enlaces para agregar nuevas entidades y para editar y eliminar las existentes.

8. Conclusión

En este tutorial, aprendimos cómo construir una aplicación web CRUD básica con Spring Boot y Thymeleaf.

Como de costumbre, todos los ejemplos de código que se muestran en el artículo están disponibles en GitHub.