Приложение Spring Boot CRUD с Thymeleaf
1. обзор
Реализация уровнейDAO, которые обеспечивают функциональность CRUD для сущностейJPA, может быть повторяющейся и трудоемкой задачей, которой мы хотим избежать в большинстве случаев. К счастью,Spring Boot упрощает создание приложений CRUD через слой стандартных репозиториев CRUD на основе JPA.
In this tutorial, we’ll learn how to develop a CRUD web application with Spring Boot and Thymeleaf.
Дальнейшее чтение:
Параметры запроса Spring с Thymeleaf
Узнайте, как использовать параметры запроса с Spring и Thymeleaf.
Изменение каталога шаблонов Thymeleaf в Spring Boot
Узнайте о местах расположения шаблонов Thymeleaf.
2. Зависимости Maven
В этом случае мы будем полагаться наspring-boot-starter-parent для простого управления зависимостями, управления версиями и настройки подключаемых модулей. В результате нам не нужно указывать версии зависимостей проекта в нашем файлеpom.xml, за исключением замены версии Java:
org.springframework.boot
spring-boot-starter-parent
2.0.6.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
1.8
Нам нужно переопределить свойство<java.version>, потому что версия Java по умолчанию, которую определяетspring-boot-starter-parent, - 1.6.
3. Уровень домена
Когда все зависимости проекта уже установлены, давайте теперь реализуем наивный уровень домена.
Для простоты этот уровень будет включать один единственный класс, который будет отвечать за моделирование сущностейUser:
@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
}
Напомним, что мы аннотировали класс аннотацией@Entity. Therefore, the JPA implementation, which is Hibernate, in this case, will be able to perform CRUD operations on the domain entities. Для ознакомления с вводным руководством по Hibernate посетите наш учебник поHibernate 5 with Spring.
Кроме того, мы ограничили поляname иemail ограничением@NotBlank. Это подразумевает, что мы можем использовать Hibernate Validator для проверки ограниченных полей перед сохранением или обновлением объекта в базе данных.
Чтобы узнать об этом, ознакомьтесь сour associated tutorial on Bean Validation.
4. Слой репозитория
На данный момент наше примерное веб-приложение ничего не делает. Но это скоро изменится.
Spring Data JPAallows us to implement JPA-based repositories (a fancy name for the DAO pattern implementation) with minimal fuss.
Spring Data JPA - ключевой компонентspring-boot-starter-data-jpa Spring Boot, который упрощает добавление функциональности CRUD с помощью мощного уровня абстракции, размещенного поверх реализации JPA. Этот уровень абстракции позволяет нам получить доступ к постоянному уровню без необходимости предоставлять наши собственные реализации DAO с нуля.
Чтобы предоставить нашему приложению базовые функции CRUD для объектовUser, все, что нам нужно сделать, это расширить интерфейсCrudRepository:
@Repository
public interface UserRepository extends CrudRepository {}
Вот и все! Просто расширив интерфейсCrudRepository, Spring Data JPA предоставит нам реализации CRUD-методов репозитория.
5. Уровень контроллера
Thanks to the layer of abstraction that spring-boot-starter-data-jpa places on top of the underlying JPA implementation, we can easily add some CRUD functionality to our web application through a basic web tier.
В нашем случае одного класса контроллера будет достаточно для обработки HTTP-запросов GET и POST, а затем сопоставить их с вызовами нашей реализацииUserRepository.
Класс контроллера основан на некоторых ключевых функциях Spring MVC. Подробное руководство по Spring MVC можно найти в нашемSpring MVC tutorial.
Начнем с методов контроллераshowSignUpForm() иaddUser().
Первый будет отображать форму регистрации пользователя, а второй сохранит новый объект в базе данных после проверки ограниченных полей.
Если объект не прошел проверку, форма регистрации будет отображена повторно. В противном случае, после сохранения объекта список сохраняемых объектов будет обновлен в соответствующем представлении:
@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);
model.addAttribute("users", userRepository.findAll());
return "index";
}
// additional CRUD methods
}
ВUserController we также будет методshowUpdateForm(), который отвечает за выборку объектаUser, который соответствует предоставленномуid из базы данных.
Если сущность существует, она будет передана как атрибут модели в представление формы обновления, следовательно, форма может быть заполнена значениями полейname иemail:
@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";
}
Наконец, у нас есть методыupdateUser() иdeleteUser() в классеUserController.
Первый сохранит обновленную сущность в базе данных, а последняя удалит данную сущность.
В любом случае список сохраняемых объектов будет обновлен соответствующим образом:
@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);
model.addAttribute("users", userRepository.findAll());
return "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);
model.addAttribute("users", userRepository.findAll());
return "index";
}
6. Слой просмотра
На этом этапе мы реализовали класс функционального контроллера, который выполняет операции CRUD с объектамиUser. Even so, there’s still a missing component in this schema: the view layer.
В папкеsrc/main/resources/templates нам нужно создать шаблоны HTML, необходимые для отображения формы регистрации, формы обновления и отображения списка сохраненных сущностейUser,
Как сказано во введении, мы будем использовать Thymeleaf в качестве основного механизма шаблонов для анализа файлов шаблонов.
Вот соответствующий раздел файлаadd-user.html:
Notice how we’ve used the @\{/adduser} URL expression to specify the form’s action attribute and the $\{} variable expressions for embedding dynamic content in the template, such as the values of the name and email fields and the post-validation errors.
Как иadd-user.html, вот как выглядит шаблонupdate-user.html:
Наконец, у нас есть файлindex.html, который отображает список сохраненных сущностей вместе со ссылками для редактирования и удаления существующих:
Для простоты шаблоны выглядят довольно скелетно и обеспечивают только необходимую функциональность без добавления ненужныхcosmetics.
Чтобы придать шаблонам улучшенный, привлекательный вид, не тратя слишком много времени на HTML / CSS, мы можем легко использовать бесплатный набор пользовательского интерфейсаTwitter Bootstrap, напримерShards.
7. Запуск приложения
Наконец, давайте определим точку входа в приложение. Как и большинство приложений Spring Boot, мы можем сделать это с помощью простого старого методаmain():
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Теперь давайте нажмем «Выполнить» в нашей среде IDE, затем откроем наш браузер и укажем наhttp://localhost:8080.
Если сборка успешно скомпилированаwe should see a basic CRUD user dashboard with links for adding new entities and for editing and removing existing ones.
8. Заключение
В этом руководстве мы узнали, как создать базовое веб-приложение CRUD с использованием Spring Boot и Thymeleaf.
Как обычно, все примеры кода, представленные в статье, доступны черезon GitHub.