Spring Boot 3.0 + Vue 3 实战:手把手教你搭建图书管理系统(附完整源码)
Spring Boot 3.0 + Vue 3 全栈实战:现代化图书管理系统开发指南
在当今快速发展的互联网时代,掌握前后端分离开发技术已成为中级开发者必备的核心竞争力。本文将带你从零开始,使用Spring Boot 3.0和Vue 3这两个当下最热门的技术栈,构建一个功能完善的图书管理系统。不同于简单的CRUD示例,我们将深入探讨现代化企业级应用开发的完整流程,包括RESTful API设计、TypeScript集成、响应式前端开发等实用技巧。
1. 项目架构设计与技术选型
1.1 为什么选择Spring Boot 3.0 + Vue 3组合
Spring Boot 3.0作为Java生态中最受欢迎的框架,带来了多项重要改进:
- GraalVM原生镜像支持:显著提升应用启动速度和内存效率
- JDK 17基线要求:充分利用现代Java特性如记录类(Records)和模式匹配
- 改进的Actuator端点:提供更全面的应用监控能力
- 响应式编程增强:简化WebFlux与数据访问层的集成
Vue 3则在前端领域带来革命性变化:
// Vue 3的组合式API示例 import { ref, onMounted } from 'vue' const bookList = ref<Book[]>([]) onMounted(async () => { const response = await fetch('/api/books') bookList.value = await response.json() })1.2 系统架构设计
我们的图书管理系统采用经典的三层架构:
客户端层 (Vue 3 + TypeScript + Pinia) ↓ API网关层 (Spring Boot 3.0) ↓ 业务逻辑层 (Spring Service) ↓ 数据访问层 (MyBatis-Plus + MySQL)提示:在实际企业项目中,建议考虑添加API网关(如Spring Cloud Gateway)和认证服务(OAuth2)来增强系统安全性。
2. 后端开发:Spring Boot 3.0实战
2.1 项目初始化与配置
使用Spring Initializr创建项目时,确保选择以下关键依赖:
- Spring Web (用于RESTful API)
- MyBatis-Plus (增强型ORM框架)
- Lombok (简化实体类编写)
- Spring Boot Actuator (应用监控)
- Spring Configuration Processor (配置提示)
# application.yml 关键配置示例 spring: datasource: url: jdbc:mysql://localhost:3306/book_management?useSSL=false username: devuser password: ${DB_PASSWORD:dev123} driver-class-name: com.mysql.cj.jdbc.Driver hikari: maximum-pool-size: 10 connection-timeout: 30000 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl map-underscore-to-camel-case: true2.2 领域模型与数据库设计
采用DDD(领域驱动设计)思想设计图书管理核心模型:
// 使用Java记录类定义实体 public record Book( Long id, String isbn, String title, String publisher, List<String> authors, LocalDateTime createdAt, LocalDateTime updatedAt ) {} // 使用MyBatis-Plus的实体类示例 @Data @TableName("books") public class Book { @TableId(type = IdType.AUTO) private Long id; @NotBlank private String title; @Pattern(regexp = "\\d{3}-\\d{10}") private String isbn; @TableField(exist = false) private List<String> authors; @TableField(fill = FieldFill.INSERT) private LocalDateTime createdAt; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updatedAt; }2.3 RESTful API设计与实现
遵循API最佳实践,我们设计以下端点:
| 端点路径 | HTTP方法 | 描述 | 成功状态码 |
|---|---|---|---|
| /api/books | GET | 获取所有图书 | 200 |
| /api/books/{id} | GET | 获取特定图书 | 200 |
| /api/books | POST | 创建新图书 | 201 |
| /api/books/{id} | PUT | 更新图书信息 | 200 |
| /api/books/{id} | DELETE | 删除图书 | 204 |
| /api/books/search | GET | 根据条件搜索图书 | 200 |
// 使用Spring Boot 3.0的RestController示例 @RestController @RequestMapping("/api/books") @RequiredArgsConstructor public class BookController { private final BookService bookService; @GetMapping public ResponseEntity<List<Book>> getAllBooks( @RequestParam(required = false) String title, @RequestParam(required = false) String publisher) { return ResponseEntity.ok(bookService.findBooks(title, publisher)); } @PostMapping public ResponseEntity<Void> addBook(@Valid @RequestBody Book book) { bookService.saveBook(book); return ResponseEntity.created(URI.create("/api/books/" + book.getId())).build(); } }3. 前端开发:Vue 3高级实践
3.1 项目初始化与架构
使用Vite创建Vue 3项目,推荐的技术栈组合:
npm create vite@latest book-management-frontend --template vue-ts关键依赖选择:
- Pinia (状态管理)
- Axios (HTTP客户端)
- Element Plus (UI组件库)
- Vue Router (路由管理)
- VueUse (实用工具集)
// main.ts 全局配置示例 import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' import router from './router' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' const app = createApp(App) app.use(createPinia()) app.use(router) app.use(ElementPlus) app.mount('#app')3.2 组件化设计与实现
采用组合式API和TypeScript强类型开发图书列表组件:
<script setup lang="ts"> import { ref, onMounted } from 'vue' import { useBookStore } from '@/stores/book' import type { Book } from '@/types' const bookStore = useBookStore() const books = ref<Book[]>([]) const loading = ref(false) onMounted(async () => { loading.value = true try { await bookStore.fetchBooks() books.value = bookStore.books } finally { loading.value = false } }) const handleDelete = async (id: number) => { // 确认对话框逻辑 await bookStore.deleteBook(id) } </script> <template> <el-table :data="books" v-loading="loading" border> <el-table-column prop="title" label="书名" width="180" /> <el-table-column prop="isbn" label="ISBN" width="150" /> <el-table-column prop="publisher" label="出版社" /> <el-table-column label="操作" width="180"> <template #default="{ row }"> <el-button size="small" @click="$router.push(`/edit/${row.id}`)"> 编辑 </el-button> <el-button size="small" type="danger" @click="handleDelete(row.id)"> 删除 </el-button> </template> </el-table-column> </el-table> </template>3.3 状态管理与API集成
使用Pinia进行状态管理,实现与后端API的交互:
// stores/book.ts import { defineStore } from 'pinia' import axios from 'axios' import type { Book } from '@/types' export const useBookStore = defineStore('book', { state: () => ({ books: [] as Book[], currentBook: null as Book | null }), actions: { async fetchBooks() { const response = await axios.get<Book[]>('/api/books') this.books = response.data }, async fetchBook(id: number) { const response = await axios.get<Book>(`/api/books/${id}`) this.currentBook = response.data }, async saveBook(book: Book) { if (book.id) { await axios.put(`/api/books/${book.id}`, book) } else { await axios.post('/api/books', book) } await this.fetchBooks() } } })4. 系统优化与进阶技巧
4.1 性能优化策略
后端优化:
- 启用Spring Boot Actuator监控端点
- 配置HikariCP连接池参数
- 添加二级缓存(Ehcache或Redis)
- 实现分页查询
// 分页查询示例 @GetMapping("/paged") public ResponseEntity<Page<Book>> getBooksPaged( @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "10") int size) { return ResponseEntity.ok(bookService.findBooksPaged(page, size)); }前端优化:
- 实现组件懒加载
- 使用Vue的keep-alive缓存组件
- 添加API请求节流
- 实现虚拟滚动长列表
// 使用VueUse实现节流 import { useThrottleFn } from '@vueuse/core' const searchQuery = ref('') const throttledSearch = useThrottleFn(() => { bookStore.searchBooks(searchQuery.value) }, 500)4.2 安全加固措施
- 后端安全:
- 添加Spring Security依赖
- 配置JWT认证过滤器
- 启用CSRF保护
- 实现输入验证
// Spring Security配置示例 @Configuration @EnableWebSecurity @RequiredArgsConstructor public class SecurityConfig { private final JwtAuthenticationFilter jwtAuthFilter; @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .csrf().disable() .authorizeHttpRequests() .requestMatchers("/api/auth/**").permitAll() .anyRequest().authenticated() .and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class); return http.build(); } }- 前端安全:
- 实现路由守卫
- 存储JWT到HttpOnly Cookie
- 添加请求拦截器
- 实现权限指令
// 路由守卫示例 router.beforeEach((to) => { const authStore = useAuthStore() if (to.meta.requiresAuth && !authStore.isAuthenticated) { return { path: '/login', query: { redirect: to.fullPath } } } })4.3 部署与持续集成
后端部署选项:
- 传统JAR部署:
java -jar book-management.jar - Docker容器化部署
- Kubernetes集群部署
- 云原生部署(如AWS ECS)
前端部署策略:
- 静态资源托管(如Nginx)
- CDN加速
- 自动化构建部署
# 前端Dockerfile示例 FROM node:18 as builder WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build FROM nginx:alpine COPY --from=builder /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]在开发过程中,我特别推荐使用Docker Compose来统一管理前后端服务,这能极大简化本地开发环境的搭建。同时,配置GitHub Actions或GitLab CI实现自动化测试和部署,可以显著提升团队协作效率。
