1. 项目概述:基于SpringBoot+Vue3+MyBatis的厨艺交流平台
这个厨艺交流平台系统采用前后端分离架构,后端使用SpringBoot框架搭建RESTful API服务,前端基于Vue3实现响应式界面,数据持久层采用MyBatis操作MySQL数据库。整套技术栈是当前企业级应用开发的黄金组合,特别适合需要快速迭代的社区类项目。
我在实际开发中发现,这种架构组合有几个显著优势:SpringBoot的自动配置让后端服务搭建变得极其高效;Vue3的Composition API使前端组件逻辑组织更清晰;MyBatis的灵活SQL编写能力可以轻松应对复杂的食谱查询需求。整套源码开箱即用,已经包含了用户认证、菜谱发布、评论互动等核心模块。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术栈选型与项目搭建
2.1 后端技术栈配置
后端采用SpringBoot 2.7.x版本,这是目前最稳定的生产环境版本。在pom.xml中需要配置以下核心依赖:
xml复制<dependencies>
<!-- SpringBoot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis整合SpringBoot -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 其他必要依赖... -->
</dependencies>
注意:MyBatis版本需要与SpringBoot版本匹配,否则会出现自动配置失败的问题。我在实际项目中遇到过2.1.x版本的starter与SpringBoot 2.7.x不兼容的情况。
2.2 前端技术栈配置
前端使用Vue3 + Vite的组合,package.json关键配置如下:
json复制{
"dependencies": {
"vue": "^3.2.47",
"vue-router": "^4.1.6",
"axios": "^1.3.4",
"element-plus": "^2.3.3",
"pinia": "^2.0.33"
},
"devDependencies": {
"vite": "^4.1.4",
"@vitejs/plugin-vue": "^4.0.0"
}
}
Vite的构建速度比传统Webpack快很多,特别适合开发阶段频繁修改的场景。Element Plus是适配Vue3的UI组件库,提供了丰富的预制组件,可以快速搭建美观的厨艺展示界面。
3. 数据库设计与MyBatis集成
3.1 MySQL数据库表结构
核心表包括用户表、菜谱表和评论表,以下是简化版的DDL:
sql复制CREATE TABLE `user` (
`id` bigint NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(100) NOT NULL,
`avatar` varchar(255) DEFAULT NULL,
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `recipe` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL,
`title` varchar(100) NOT NULL,
`cover_image` varchar(255) DEFAULT NULL,
`content` text,
`view_count` int DEFAULT '0',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `comment` (
`id` bigint NOT NULL AUTO_INCREMENT,
`recipe_id` bigint NOT NULL,
`user_id` bigint NOT NULL,
`content` varchar(500) NOT NULL,
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_recipe_id` (`recipe_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3.2 MyBatis动态SQL应用
MyBatis的强大之处在于其动态SQL能力,这在菜谱搜索功能中特别有用。例如实现多条件菜谱查询:
xml复制<select id="selectRecipes" resultType="com.example.entity.Recipe">
SELECT * FROM recipe
<where>
<if test="title != null and title != ''">
AND title LIKE CONCAT('%', #{title}, '%')
</if>
<if test="userId != null">
AND user_id = #{userId}
</if>
<if test="minViewCount != null">
AND view_count >= #{minViewCount}
</if>
</where>
ORDER BY create_time DESC
</select>
实际开发中发现,MyBatis的#{}和${}有重要区别:#{}会预编译防止SQL注入,而${}直接拼接SQL,在用户输入处必须使用#{}。
4. 前后端分离架构实现
4.1 RESTful API设计规范
后端API遵循RESTful设计原则,主要端点示例:
| 端点 | 方法 | 描述 |
|---|---|---|
| /api/auth/login | POST | 用户登录 |
| /api/recipes | GET | 获取菜谱列表 |
| /api/recipes/ | GET | 获取单个菜谱详情 |
| /api/recipes | POST | 创建新菜谱 |
| /api/recipes/{id}/comments | GET | 获取菜谱评论 |
SpringBoot中实现示例:
java复制@RestController
@RequestMapping("/api/recipes")
public class RecipeController {
@Autowired
private RecipeService recipeService;
@GetMapping
public ResponseEntity<List<Recipe>> listRecipes(
@RequestParam(required = false) String title,
@RequestParam(required = false) Long userId) {
List<Recipe> recipes = recipeService.findByCriteria(title, userId);
return ResponseEntity.ok(recipes);
}
@PostMapping
public ResponseEntity<Recipe> createRecipe(
@RequestBody Recipe recipe,
@AuthenticationPrincipal User user) {
recipe.setUserId(user.getId());
Recipe saved = recipeService.save(recipe);
return ResponseEntity.status(HttpStatus.CREATED).body(saved);
}
}
4.2 前端Vue3组件实现
前端使用Pinia进行状态管理,菜谱列表组件示例:
vue复制<script setup>
import { ref, onMounted } from 'vue'
import { useRecipeStore } from '@/stores/recipe'
const recipeStore = useRecipeStore()
const recipes = ref([])
const isLoading = ref(false)
onMounted(async () => {
isLoading.value = true
try {
await recipeStore.fetchRecipes()
recipes.value = recipeStore.recipes
} finally {
isLoading.value = false
}
})
</script>
<template>
<div v-if="isLoading">加载中...</div>
<div v-else>
<div v-for="recipe in recipes" :key="recipe.id" class="recipe-card">
<img :src="recipe.coverImage" :alt="recipe.title">
<h3>{{ recipe.title }}</h3>
<p>{{ recipe.content.substring(0, 100) }}...</p>
</div>
</div>
</template>
5. 项目部署与性能优化
5.1 生产环境配置
SpringBoot应用的生产配置需要注意以下几点:
- 数据库连接池配置(application-prod.yml):
yaml复制spring:
datasource:
url: jdbc:mysql://prod-db:3306/cooking_db?useSSL=false&characterEncoding=utf8
username: prod_user
password: ${DB_PASSWORD}
hikari:
maximum-pool-size: 20
connection-timeout: 30000
- MyBatis二级缓存配置:
xml复制<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
5.2 前端性能优化
Vue3项目通过以下方式优化:
- 路由懒加载:
javascript复制const routes = [
{
path: '/recipes',
component: () => import('@/views/RecipesView.vue')
}
]
- 静态资源CDN部署:
javascript复制// vite.config.js
export default defineConfig({
build: {
rollupOptions: {
output: {
chunkFileNames: 'static/js/[name]-[hash].js',
assetFileNames: 'static/[ext]/[name]-[hash].[ext]'
}
}
}
})
6. 常见问题与解决方案
在开发过程中遇到的一些典型问题及解决方法:
-
MyBatis映射问题:
- 现象:查询返回的字段值为null
- 解决:检查实体类属性名与数据库列名是否一致,或使用@Results注解显式映射
-
Vue3响应式丢失:
- 现象:修改数组后视图不更新
- 解决:使用reactive()包装对象,数组操作使用push/splice等方法
-
跨域问题:
- 现象:前端请求被浏览器拦截
- 解决:SpringBoot中添加@CrossOrigin注解或全局CORS配置
-
MySQL连接超时:
- 现象:长时间闲置后连接断开
- 解决:配置连接池的testWhileIdle和validationQuery参数
这个项目完整展示了如何将SpringBoot、Vue3和MyBatis这三个强大框架有机结合,构建一个功能完善的厨艺交流平台。源码中已经包含了用户认证、内容管理、互动评论等核心功能模块,开发者可以基于此快速扩展更多个性化功能。
