SpringBoot+Vue+MySQL美食网站系统开发实战
1. 项目概述今天要分享的是一个基于SpringBootVueMySQL的美食网站信息管理系统完整实现方案。这个系统是我在指导某高校计算机专业毕业设计时开发的实战项目经过多次迭代已经成为一个可直接用于生产环境的解决方案。作为一个典型的BS架构应用系统采用前后端分离设计后端使用SpringBoot提供RESTful API前端采用Vue.js构建响应式界面数据库选用MySQL 8.0。这种技术组合在当前企业级应用开发中非常主流既能保证系统性能又能快速迭代开发。系统核心功能包括用户注册登录与个人中心管理美食信息浏览与搜索餐厅详情与菜品展示用户评论与互动收藏与评分系统商家后台管理2. 技术架构解析2.1 后端技术栈后端采用SpringBoot 2.7作为基础框架这是我经过多个项目验证后的稳定选择。相比传统SSM框架SpringBoot的自动配置和起步依赖能显著减少样板代码内置Tomcat服务器也简化了部署流程。关键组件配置// pom.xml核心依赖 dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-jpa/artifactId /dependency dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.28/version /dependency dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt/artifactId version0.9.1/version /dependency /dependencies安全认证采用JWT(JSON Web Token)方案相比传统Session方式更符合RESTful无状态原则也便于移动端集成。我在实现时特别增加了token自动续期机制当token即将过期时自动生成新token返回给客户端。2.2 前端技术栈前端使用Vue 3组合式API开发配合Element Plus组件库快速构建界面。项目采用Vite作为构建工具相比Webpack启动速度提升明显热更新几乎瞬间完成。目录结构设计src/ ├── api/ # 接口请求封装 ├── assets/ # 静态资源 ├── components/ # 公共组件 ├── composables/ # 组合式函数 ├── router/ # 路由配置 ├── stores/ # Pinia状态管理 ├── utils/ # 工具函数 └── views/ # 页面组件特别优化了图片懒加载和虚拟滚动技术在美食列表页即使加载大量图片也能保持流畅体验。实测在1000条数据情况下首屏渲染时间控制在1.5秒内。2.3 数据库设计MySQL表设计遵循第三范式同时针对查询性能做了适当反范式优化。所有表都使用InnoDB引擎支持事务和行级锁。下面是核心表结构用户表(user_profile)CREATE TABLE user_profile ( user_id bigint NOT NULL AUTO_INCREMENT, username varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, password_hash varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, email varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, phone_number varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL, avatar_url varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, register_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, last_login datetime DEFAULT NULL, status tinyint NOT NULL DEFAULT 0, PRIMARY KEY (user_id), UNIQUE KEY idx_username (username), UNIQUE KEY idx_email (email) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci;美食表(food_item)CREATE TABLE food_item ( food_id bigint NOT NULL AUTO_INCREMENT, food_name varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL, restaurant_id bigint NOT NULL, category_tag varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL, description text COLLATE utf8mb4_unicode_ci, price decimal(10,2) NOT NULL, image_url varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, publish_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, rating float DEFAULT 0, PRIMARY KEY (food_id), KEY idx_restaurant (restaurant_id), KEY idx_category (category_tag) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci;3. 核心功能实现3.1 用户认证模块采用JWT实现无状态认证解决分布式系统session共享问题。Token中只存储用户ID和必要信息敏感数据通过数据库实时查询获取。认证流程关键代码// JWT工具类 public class JwtUtil { private static final String SECRET_KEY your-256-bit-secret; private static final long EXPIRATION_TIME 86400000; // 24小时 public static String generateToken(UserDetails userDetails) { return Jwts.builder() .setSubject(userDetails.getUsername()) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() EXPIRATION_TIME)) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); } public static boolean validateToken(String token) { try { Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token); return true; } catch (Exception e) { // 处理各种异常情况 return false; } } }安全提示实际项目中SECRET_KEY应该从配置中心获取不要硬编码在代码中。同时建议定期轮换密钥。3.2 美食搜索功能实现基于Elasticsearch的全文检索支持关键词搜索、分类筛选和距离排序。对于中小型项目也可以先用MySQL全文索引过渡。MySQL全文检索实现-- 创建全文索引 ALTER TABLE food_item ADD FULLTEXT INDEX ft_index (food_name, description); -- 执行搜索 SELECT food_id, food_name, MATCH(food_name, description) AGAINST(火锅 IN NATURAL LANGUAGE MODE) AS score FROM food_item WHERE MATCH(food_name, description) AGAINST(火锅 IN NATURAL LANGUAGE MODE) ORDER BY score DESC LIMIT 10;3.3 评论互动系统采用乐观锁解决并发点赞问题避免使用行锁影响性能。评论表设计考虑了分页查询效率通过复合索引优化查询速度。评论分页查询优化Repository public interface ReviewRepository extends JpaRepositoryReview, Long { Query(value SELECT r FROM Review r WHERE r.foodId :foodId ORDER BY r.reviewTime DESC, countQuery SELECT COUNT(r) FROM Review r WHERE r.foodId :foodId) PageReview findByFoodId(Param(foodId) Long foodId, Pageable pageable); }4. 部署与运维4.1 本地开发环境搭建安装JDK 17、Node.js 16和MySQL 8.0克隆项目仓库后端配置cd backend cp application-sample.properties application.properties # 修改数据库配置 mvn spring-boot:run前端配置cd frontend npm install npm run dev4.2 生产环境部署推荐使用Docker容器化部署便于扩展和维护。编写了完整的docker-compose.yml文件一键启动所有服务。数据库连接池配置建议# application-prod.properties spring.datasource.urljdbc:mysql://mysql:3306/food_db?useSSLfalse spring.datasource.usernameroot spring.datasource.passwordyourpassword spring.datasource.hikari.maximum-pool-size20 spring.datasource.hikari.connection-timeout30000 spring.datasource.hikari.idle-timeout600000 spring.datasource.hikari.max-lifetime18000005. 常见问题解决5.1 跨域问题开发环境下可在前端配置代理生产环境建议通过Nginx解决location /api/ { proxy_pass http://backend:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }5.2 图片上传限制SpringBoot默认文件上传限制为1MB需要调整配置spring.servlet.multipart.max-file-size10MB spring.servlet.multipart.max-request-size10MB前端Element Upload组件需要对应设置el-upload action/api/upload :limit3 :on-exceedhandleExceed :before-uploadbeforeUpload :data{type: food} el-button typeprimary点击上传/el-button /el-upload script export default { methods: { beforeUpload(file) { const isJPG file.type image/jpeg; const isLt10M file.size / 1024 / 1024 10; if (!isJPG) { this.$message.error(只能上传JPEG图片!); } if (!isLt10M) { this.$message.error(图片大小不能超过10MB!); } return isJPG isLt10M; } } } /script6. 性能优化实践6.1 缓存策略采用多级缓存架构前端使用localStorage缓存静态资源和API响应后端使用Redis缓存热点数据MySQL查询缓存Redis配置示例Configuration EnableCaching public class RedisConfig { Bean public RedisCacheManager cacheManager(RedisConnectionFactory factory) { RedisCacheConfiguration config RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofMinutes(30)) .disableCachingNullValues() .serializeValuesWith(SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())); return RedisCacheManager.builder(factory) .cacheDefaults(config) .transactionAware() .build(); } }6.2 数据库优化为所有外键字段添加索引大文本字段使用TEXT类型并单独查询定期执行ANALYZE TABLE更新统计信息配置合适的innodb_buffer_pool_size建议为物理内存的70%7. 扩展与定制系统设计时已考虑扩展性以下是一些可能的扩展方向增加第三方登录微信、微博等实现基于用户行为的推荐系统接入支付系统实现在线订餐开发商家端APP增加会员积分体系对于毕业设计使用建议根据具体需求选择1-2个扩展点深入实现不必追求大而全。我在项目中预留了相应的接口和扩展点二次开发时会发现很多便利的设计。