1. 项目背景与技术选型解析
这个毕业设计系统采用了当前企业级开发中最主流的全栈技术组合:SpringBoot+Vue3+MyBatis。这种架构模式完美体现了前后端分离的开发思想,也是目前互联网公司实际项目中的标配方案。
为什么说这个技术栈组合值得学习?从我的实际项目经验来看:
-
SpringBoot 作为Java后端开发的"瑞士军刀",通过自动配置和起步依赖大幅简化了传统SSM框架的搭建过程。我经手过的电商系统中,用SpringBoot相比原生Spring项目能减少约60%的XML配置量。
-
Vue3 的Composition API让前端组件逻辑组织更灵活。去年我们团队重构管理系统时,将Vue2升级到Vue3后,相同功能的代码量减少了35%,特别是setup语法对TypeScript的支持让代码提示更加智能。
-
MyBatis 在复杂SQL场景下的优势非常明显。做过一个报表系统,需要动态生成包含20+关联表的查询语句,MyBatis的动态SQL功能比JPA的Criteria查询直观得多。
数据库选择MySQL也是经过深思熟虑的:
- 作为最流行的开源关系型数据库,MySQL5.7+版本已经支持JSON类型和窗口函数
- 在Web应用中80%以上的场景对事务要求是ACID中的AID(原子性、隔离性、持久性)
- 配合InnoDB引擎,单表千万级数据量下仍能保持良好性能
提示:新手常犯的错误是直接开写代码而不考虑技术选型。建议先用1天时间做技术对比,这能避免后期大量重构工作。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 开发环境搭建与项目初始化
2.1 后端工程脚手架搭建
使用Spring Initializr创建项目时,这几个依赖是必选的:
xml复制<dependencies>
<!-- Web核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis整合 -->
<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>
<!-- Lombok简化代码 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
application.yml的数据库配置要注意时区问题:
yaml复制spring:
datasource:
url: jdbc:mysql://localhost:3306/graduation?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
2.2 前端工程初始化
用Vite创建Vue3项目比传统webpack快很多:
bash复制npm create vite@latest frontend --template vue-ts
必须安装的核心依赖:
bash复制npm install axios vue-router@4 pinia element-plus
axios拦截器的典型配置:
typescript复制// src/utils/request.ts
const service = axios.create({
baseURL: import.meta.env.VITE_APP_BASE_API,
timeout: 5000
})
// 请求拦截
service.interceptors.request.use(config => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
})
// 响应拦截
service.interceptors.response.use(
response => {
return response.data
},
error => {
return Promise.reject(error)
}
)
3. 核心模块设计与实现
3.1 用户认证模块
JWT认证的后端实现要点:
java复制// JwtUtils.java
public class JwtUtils {
private static final String SECRET = "graduation-system";
private static final long EXPIRATION = 86400L; // 24小时
public static String generateToken(UserDetails userDetails) {
return Jwts.builder()
.setSubject(userDetails.getUsername())
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION * 1000))
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
}
public static String getUsernameFromToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token)
.getBody()
.getSubject();
}
}
Spring Security配置类关键代码:
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
3.2 动态路由与权限控制
前端路由守卫的典型实现:
typescript复制// src/router/index.ts
router.beforeEach(async (to, from, next) => {
const token = localStorage.getItem('token')
if (to.path === '/login') {
if (token) return next('/dashboard')
return next()
}
if (!token) return next('/login')
if (!store.state.user.roles) {
try {
await store.dispatch('user/getUserInfo')
const accessRoutes = await store.dispatch('permission/generateRoutes')
accessRoutes.forEach(route => router.addRoute(route))
next({ ...to, replace: true })
} catch (error) {
next(`/login?redirect=${to.path}`)
}
} else {
next()
}
})
后端接口权限校验建议使用注解方式:
java复制@PreAuthorize("hasRole('ADMIN')")
@GetMapping("/admin/users")
public Result<List<User>> getUserList() {
return Result.success(userService.list());
}
4. 前后端交互规范与性能优化
4.1 接口设计规范
推荐使用统一的响应体结构:
java复制@Data
public class Result<T> {
private int code;
private String message;
private T data;
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>();
result.setCode(200);
result.setMessage("success");
result.setData(data);
return result;
}
}
前端API调用示例:
typescript复制// src/api/user.ts
export function getUserList(params: ListQuery) {
return request<PageResult<UserItem>>({
url: '/api/users',
method: 'get',
params
})
}
4.2 性能优化实践
- MyBatis二级缓存配置:
xml复制<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- 在Mapper.xml中 -->
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
- Vue3组件性能优化:
vue复制<script setup>
import { computed } from 'vue'
const props = defineProps(['list'])
const sortedList = computed(() => {
return [...props.list].sort((a, b) => a.id - b.id)
})
</script>
<template>
<div v-for="item in sortedList" :key="item.id">
{{ item.name }}
</div>
</template>
- SpringBoot应用优化:
properties复制# application.properties
server.tomcat.max-threads=200
server.tomcat.accept-count=100
spring.datasource.hikari.maximum-pool-size=20
spring.jpa.open-in-view=false
5. 常见问题排查与调试技巧
5.1 跨域问题解决方案
SpringBoot后端配置:
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.maxAge(3600);
}
}
开发环境也可以在vite.config.ts中配置代理:
typescript复制export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true
}
}
}
})
5.2 MyBatis常见异常处理
- 参数绑定异常:
xml复制<!-- 错误写法 -->
<select id="getUser" parameterType="String" resultType="User">
SELECT * FROM user WHERE username = #{username}
</select>
<!-- 正确写法 -->
<select id="getUser" resultType="User">
SELECT * FROM user WHERE username = #{username}
</select>
- 动态SQL使用注意:
xml复制<select id="findUsers" resultType="User">
SELECT * FROM user
<where>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="status != null">
AND status = #{status}
</if>
</where>
ORDER BY id DESC
</select>
5.3 Vue3开发调试技巧
- 组合式API的调试:
typescript复制import { ref, onMounted } from 'vue'
const count = ref(0)
// 在Chrome开发者工具中可以直接访问
window.__count = count
onMounted(() => {
console.log('mounted')
})
- Pinia状态调试:
typescript复制// 在main.ts中
const pinia = createPinia()
pinia.use(({ store }) => {
window[`__store_${store.$id}`] = store
})
app.use(pinia)
6. 数据库设计与优化建议
6.1 表结构设计示例
用户表设计:
sql复制CREATE TABLE `sys_user` (
`id` bigint NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(100) NOT NULL COMMENT '密码',
`salt` varchar(20) DEFAULT NULL COMMENT '加密盐值',
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`phone` varchar(20) DEFAULT NULL COMMENT '手机号',
`avatar` varchar(255) DEFAULT NULL COMMENT '头像',
`status` tinyint DEFAULT '1' COMMENT '状态 0:禁用 1:正常',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
6.2 索引优化原则
-
索引建立策略:
- 为WHERE子句中的列建立索引
- 为JOIN关联列建立索引
- 为ORDER BY/GROUP BY列建立索引
- 避免在区分度低的列上建索引(如性别)
-
执行计划分析:
sql复制EXPLAIN SELECT * FROM sys_user WHERE username = 'admin';
- 常见索引失效场景:
- 使用!=或<>操作符
- 对列进行函数运算
- 使用OR条件但未对所有条件列建索引
- 使用LIKE以通配符开头
7. 项目部署与运维方案
7.1 后端打包与运行
SpringBoot打包为可执行JAR:
bash复制mvn clean package -DskipTests
java -jar target/graduation-system.jar --spring.profiles.active=prod
推荐使用Docker部署:
dockerfile复制FROM openjdk:11-jre
COPY target/graduation-system.jar /app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
7.2 前端生产环境构建
Vue3项目构建命令:
bash复制npm run build
Nginx配置示例:
nginx复制server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://backend:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
7.3 监控与日志管理
SpringBoot Actuator配置:
yaml复制management:
endpoints:
web:
exposure:
include: health,info,metrics
endpoint:
health:
show-details: always
日志收集建议方案:
xml复制<!-- logback-spring.xml -->
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/app.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE"/>
</root>
</configuration>
8. 毕业设计扩展方向建议
- 引入消息队列:用RabbitMQ实现异步通知功能
- 接入第三方服务:整合支付宝沙箱环境实现支付功能
- 增加数据分析:使用ECharts实现数据可视化报表
- 实现分布式架构:将认证服务拆分为独立微服务
- 增强安全防护:整合Spring Security OAuth2
- 自动化测试:编写JUnit单元测试和Cypress端到端测试
- CI/CD流水线:配置GitHub Actions自动化部署
我在实际指导毕业设计时发现,选择1-2个扩展方向深入实现,比泛泛而谈多个技术点更能获得高分。特别是消息队列和数据分析这两个方向,既有技术深度又容易出可视化成果。
