1. 概述
在开发中,针对 JPA 实体实现 DAO 层的 CRUD(增删改查)功能往往是一个重复且耗时的过程。我们通常希望避免这种机械性工作。
幸运的是,Spring Boot 提供了基于标准 JPA 的 CRUD Repository 层,可以极大简化这一过程。
本教程将带你一步步使用 Spring Boot 和 Thymeleaf 构建一个完整的 CRUD Web 应用程序。
2. Maven 依赖配置
为了简化依赖管理和版本控制,我们使用 spring-boot-starter-parent
作为父项目。
因此,在 pom.xml
中我们无需显式指定依赖版本(除了 Java 版本):
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>
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;
// 标准构造函数 / setter / getter / toString 省略
}
⚠️ 注意:使用了 @Entity
注解,这样 Hibernate(JPA 的实现)就可以对这个实体进行 CRUD 操作了。
另外,我们对 name
和 email
字段使用了 @NotBlank
注解约束,这意味着在保存或更新前可以借助 Hibernate Validator 做字段校验。
如需了解更多,可参考 Bean Validation 教程。
4. Repository 层
目前我们的应用还啥也干不了,不过马上就好。
Spring Data JPA 提供了一种非常简洁的方式来实现 JPA 的 Repository(也就是 DAO 模式的实现)。
它是 spring-boot-starter-data-jpa
的核心组件,通过在 JPA 实现之上封装了一层强大的抽象,让我们无需从零开始编写 DAO 实现。
✅ 要为 User
实体提供基础的 CRUD 功能,只需继承 CrudRepository
接口:
@Repository
public interface UserRepository extends CrudRepository<User, Long> {}
就是这么简单!Spring Data JPA 会自动为我们实现 CRUD 方法。
5. 控制层设计
借助 Spring Data JPA 的抽象层,我们可以轻松在 Web 层添加 CRUD 功能。
我们只需要一个 Controller 来处理 GET 和 POST 请求,并调用 UserRepository
即可。
以下是 Controller 的部分核心方法:
@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";
}
// 其他 CRUD 方法略
}
显示用户列表
@GetMapping("/index")
public String showUserList(Model model) {
model.addAttribute("users", userRepository.findAll());
return "index";
}
编辑用户表单
@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";
}
更新 & 删除用户
@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. 视图层构建
我们已经有了功能完整的 Controller,但还差一步:视图层。
在 src/main/resources/templates
目录下创建以下 Thymeleaf 模板文件:
新增用户表单 add-user.html
<form action="#" th:action="@{/adduser}" th:object="${user}" method="post">
<label for="name">Name</label>
<input type="text" th:field="*{name}" id="name" placeholder="Name">
<span th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></span>
<label for="email">Email</label>
<input type="text" th:field="*{email}" id="email" placeholder="Email">
<span th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></span>
<input type="submit" value="Add User">
</form>
更新用户表单 update-user.html
<form action="#"
th:action="@{/update/{id}(id=${user.id})}"
th:object="${user}"
method="post">
<label for="name">Name</label>
<input type="text" th:field="*{name}" id="name" placeholder="Name">
<span th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></span>
<label for="email">Email</label>
<input type="text" th:field="*{email}" id="email" placeholder="Email">
<span th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></span>
<input type="submit" value="Update User">
</form>
用户列表页面 index.html
<div th:switch="${users}">
<h2 th:case="null">No users yet!</h2>
<div th:case="*">
<h2>Users</h2>
<table>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr th:each="user : ${users}">
<td th:text="${user.name}"></td>
<td th:text="${user.email}"></td>
<td><a th:href="@{/edit/{id}(id=${user.id})}">Edit</a></td>
<td><a th:href="@{/delete/{id}(id=${user.id})}">Delete</a></td>
</tr>
</tbody>
</table>
</div>
<p><a href="/signup">Add a new user</a></p>
</div>
💡 提示:模板结构简单,功能为主。如需美化界面,可引入 Bootstrap 或 Shards 等 UI 框架。
7. 启动应用
最后一步,定义应用入口:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
运行项目后,访问 http://localhost:8080 即可看到一个完整的用户管理界面。
✅ 功能包括:新增用户、编辑、删除、列表展示。
8. 总结
本文带你从零开始,使用 Spring Boot 和 Thymeleaf 构建了一个完整的 CRUD Web 应用。
所有代码示例均可在 GitHub 获取。