1. 项目概述:前后端分离编程训练系统
这套基于SpringBoot+Vue+MyBatis+MySQL的技术栈实现的编程训练系统,采用了典型的前后端分离架构。前端使用Vue.js构建用户界面,后端采用SpringBoot提供RESTful API,数据持久层通过MyBatis与MySQL数据库交互。这种架构模式在当前企业级应用开发中已成为主流选择,特别适合需要快速迭代的教学类系统开发。
我在实际开发中发现,这种技术组合特别适合编程训练类系统,主要因为:
- Vue的响应式特性能够实时反映代码执行结果
- SpringBoot的自动配置简化了教学环境部署
- MyBatis的SQL可控性适合教学场景的调试需求
- MySQL的稳定性和普及度保障了系统可靠性
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术栈深度解析
2.1 SpringBoot后端设计
后端采用SpringBoot 2.7.x版本,这是目前企业应用最稳定的版本之一。核心配置要点包括:
java复制// 应用主类配置示例
@SpringBootApplication
@MapperScan("com.coding.train.mapper")
public class TrainApplication {
public static void main(String[] args) {
SpringApplication.run(TrainApplication.class, args);
}
}
关键依赖配置(pom.xml):
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>
</dependencies>
注意:实际开发中建议使用SpringBoot的版本管理,避免直接指定第三方依赖版本号
2.2 Vue前端架构
前端采用Vue 3组合式API,项目结构设计如下:
code复制/src
/api - 接口定义
/assets - 静态资源
/components - 公共组件
/router - 路由配置
/store - 状态管理
/views - 页面组件
核心路由配置示例:
javascript复制const routes = [
{
path: '/problems',
component: () => import('../views/ProblemList.vue'),
meta: { requiresAuth: true }
},
{
path: '/submit/:id',
component: () => import('../views/CodeSubmit.vue')
}
]
2.3 MyBatis数据层实现
MyBatis的Mapper接口与XML配置采用最新最佳实践:
java复制@Mapper
public interface ProblemMapper {
@Select("SELECT * FROM coding_problems WHERE id = #{id}")
Problem getProblemById(Long id);
@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("INSERT INTO coding_problems(title, description) VALUES(#{title}, #{description})")
int insertProblem(Problem problem);
}
对应的XML映射文件:
xml复制<mapper namespace="com.coding.train.mapper.SubmissionMapper">
<resultMap id="SubmissionResult" type="Submission">
<id property="id" column="id"/>
<result property="code" column="code_content"/>
<result property="status" column="judge_status"/>
</resultMap>
<select id="getUserSubmissions" resultMap="SubmissionResult">
SELECT * FROM code_submissions
WHERE user_id = #{userId}
ORDER BY submit_time DESC
</select>
</mapper>
3. 核心功能实现
3.1 在线代码执行模块
这是系统的核心功能,实现要点包括:
- 使用Docker沙箱隔离代码执行环境
- 通过Redis队列管理判题任务
- 实现WebSocket实时返回执行结果
后端判题服务核心逻辑:
java复制@RestController
@RequestMapping("/api/judge")
public class JudgeController {
@Autowired
private JudgeQueueService judgeQueueService;
@PostMapping("/submit")
public ResponseEntity<SubmissionResult> submitCode(
@RequestBody CodeSubmission submission) {
String taskId = UUID.randomUUID().toString();
judgeQueueService.addJudgeTask(taskId, submission);
return ResponseEntity.ok(new SubmissionResult(taskId, "PENDING"));
}
}
前端调用示例:
javascript复制const submitCode = async (code, problemId) => {
const response = await axios.post('/api/judge/submit', {
code,
problemId,
language: 'java'
});
connectWebSocket(response.data.taskId);
}
3.2 用户认证与授权
采用JWT实现无状态认证,关键配置:
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);
}
}
前端axios拦截器配置:
javascript复制axios.interceptors.request.use(config => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
4. 系统部署实践
4.1 开发环境搭建
-
后端环境:
- JDK 11+
- Maven 3.6+
- MySQL 8.0
-
前端环境:
- Node.js 16+
- npm 8+
初始化数据库:
sql复制CREATE DATABASE coding_train DEFAULT CHARACTER SET utf8mb4;
CREATE USER 'train_user'@'%' IDENTIFIED BY 'secure_password';
GRANT ALL PRIVILEGES ON coding_train.* TO 'train_user'@'%';
4.2 生产环境部署
推荐使用Docker Compose部署:
yaml复制version: '3.8'
services:
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
- redis
frontend:
build: ./frontend
ports:
- "80:80"
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: coding_train
MYSQL_USER: train_user
MYSQL_PASSWORD: userpass
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:6-alpine
volumes:
mysql_data:
重要提示:生产环境务必配置HTTPS,可以使用Nginx反向代理实现
5. 常见问题与解决方案
5.1 跨域问题处理
后端配置CORS(SpringBoot):
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8081")
.allowedMethods("*")
.allowedHeaders("*")
.allowCredentials(true);
}
}
前端开发环境代理配置(vue.config.js):
javascript复制module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true
}
}
}
}
5.2 MyBatis映射问题
常见问题及解决:
-
字段映射失败:
- 检查数据库字段命名风格(下划线转驼峰需配置)
xml复制<settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> -
动态SQL编写:
xml复制<select id="searchProblems" resultType="Problem"> SELECT * FROM coding_problems <where> <if test="keyword != null"> AND title LIKE CONCAT('%', #{keyword}, '%') </if> <if test="difficulty != null"> AND difficulty = #{difficulty} </if> </where> </select>
5.3 Vue性能优化
-
路由懒加载:
javascript复制const ProblemDetail = () => import('./views/ProblemDetail.vue') -
API请求节流:
javascript复制import _ from 'lodash'; const searchProblems = _.debounce(async (keyword) => { const res = await api.searchProblems(keyword); // 处理结果 }, 500); -
状态管理优化:
javascript复制// 使用Pinia替代Vuex import { defineStore } from 'pinia'; export const useProblemStore = defineStore('problem', { state: () => ({ problems: [], currentProblem: null }), actions: { async fetchProblems() { this.problems = await api.getProblems(); } } });
6. 项目扩展方向
在实际使用中,可以考虑以下扩展:
-
代码自动评测增强:
- 支持更多编程语言(Python、C++等)
- 添加静态代码分析功能
- 实现代码相似度检测
-
教学功能扩展:
- 添加课程管理系统
- 实现学习进度跟踪
- 开发在线IDE集成
-
性能优化:
- 引入Redis缓存高频访问数据
- 实现后端API的响应式编程改造
- 添加前端静态资源CDN加速
技术选型建议:
- 实时通信:考虑WebSocket或SSE
- 文件存储:MinIO或阿里云OSS
- 监控:Prometheus + Grafana
这套系统我在实际部署中发现,对于50人以下的教学班级,2核4G的云服务器即可流畅运行。当用户量增大时,可以考虑将判题服务独立部署,使用消息队列进行任务分发。
