这套基于SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0的在线课程管理系统,正是当前教育信息化转型浪潮中的典型技术实践。我在实际开发教育类系统时发现,一个完整的课程管理平台需要同时满足三个核心诉求:稳定的后台服务能力、流畅的前端交互体验以及可靠的数据存储方案。这个技术栈组合恰好完美覆盖了这些需求点。
系统采用前后端分离架构,后端使用SpringBoot2构建RESTful API服务,前端采用Vue3实现动态交互界面,通过MyBatis-Plus高效操作MySQL8.0数据库。这种架构模式既保证了系统的可维护性,又能充分发挥各技术组件的优势。特别值得一提的是,项目还提供了完整的开发文档,这对学习者理解系统架构和二次开发都大有裨益。
SpringBoot2作为当前Java领域最主流的微服务框架,在这个系统中承担着核心业务逻辑处理的重任。我在多个教育项目中的实践表明,SpringBoot2的自动配置特性可以快速搭建起稳定的课程管理后台:
java复制@SpringBootApplication
public class CourseApplication {
public static void main(String[] args) {
SpringApplication.run(CourseApplication.class, args);
}
}
这样一个简单的启动类,就已经包含了Tomcat服务器、Spring MVC等核心组件的自动配置。对于课程管理系统来说,特别有价值的几个SpringBoot2特性包括:
提示:在实际部署时,建议通过application.yml配置server.servlet.session.timeout参数,合理设置课程学习会话的过期时间。
前端采用Vue3的组合式API开发课程管理界面,相比Options API有更清晰的逻辑组织方式。下面是一个典型的课程列表组件实现:
vue复制<script setup>
import { ref, onMounted } from 'vue'
import { getCourseList } from '@/api/course'
const courses = ref([])
onMounted(async () => {
courses.value = await getCourseList()
})
</script>
Vue3在这个系统中的几个关键应用点:
MyBatis-Plus作为MyBatis的增强工具,极大简化了课程数据的CRUD操作。例如定义课程实体映射:
java复制@Data
@TableName("t_course")
public class Course {
@TableId(type = IdType.AUTO)
private Long id;
private String title;
private String coverUrl;
private Integer status;
// 其他字段...
}
对应的Mapper接口只需简单继承BaseMapper即可获得全套数据操作方法:
java复制public interface CourseMapper extends BaseMapper<Course> {
// 自定义复杂查询
@Select("SELECT * FROM t_course WHERE status = #{status}")
List<Course> selectByStatus(@Param("status") Integer status);
}
在实际开发中,我特别推荐使用MyBatis-Plus的Lambda查询方式,既能保证类型安全,又具有很好的可读性:
java复制List<Course> activeCourses = courseMapper.selectList(
Wrappers.<Course>lambdaQuery()
.eq(Course::getStatus, 1)
.orderByDesc(Course::getCreateTime)
);
MySQL8.0为课程管理系统带来了几个关键改进:
例如统计每个学生的课程学习进度排名:
sql复制SELECT
student_id,
course_id,
progress,
RANK() OVER (PARTITION BY course_id ORDER BY progress DESC) AS rank_in_course
FROM t_learning_progress;
课程管理作为系统的核心模块,其数据库设计需要考虑多种教学场景:
sql复制CREATE TABLE `t_course` (
`id` bigint NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL COMMENT '课程名称',
`subtitle` varchar(200) DEFAULT NULL COMMENT '副标题',
`cover_url` varchar(255) DEFAULT NULL COMMENT '封面图URL',
`teacher_id` bigint NOT NULL COMMENT '授课教师',
`category_id` int DEFAULT NULL COMMENT '分类ID',
`price` decimal(10,2) DEFAULT '0.00' COMMENT '课程价格',
`status` tinyint DEFAULT '0' COMMENT '状态:0-未发布 1-已发布',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
后端接口设计遵循RESTful规范:
code复制GET /api/courses - 获取课程列表
POST /api/courses - 创建新课程
GET /api/courses/{id} - 获取课程详情
PUT /api/courses/{id} - 更新课程信息
DELETE /api/courses/{id} - 删除课程
学生端的学习流程涉及多个服务的协同:
典型的学习进度更新逻辑:
java复制public class LearningService {
@Transactional
public void updateProgress(Long userId, Long courseId, Long videoId, Integer progress) {
// 检查课程有效性
Course course = courseMapper.selectById(courseId);
if (course == null || course.getStatus() != 1) {
throw new BusinessException("课程不可用");
}
// 更新学习进度
LambdaUpdateWrapper<LearningProgress> updateWrapper = Wrappers.lambdaUpdate();
updateWrapper.eq(LearningProgress::getUserId, userId)
.eq(LearningProgress::getCourseId, courseId)
.set(LearningProgress::getLastLearnVideoId, videoId)
.set(LearningProgress::getProgress, progress)
.set(LearningProgress::getUpdateTime, new Date());
if (learningProgressMapper.update(null, updateWrapper) == 0) {
LearningProgress newProgress = new LearningProgress();
// 设置各字段值...
learningProgressMapper.insert(newProgress);
}
// 记录学习行为
studyBehaviorService.record(userId, courseId, videoId);
}
}
基于Spring Security的权限控制配置:
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/api/admin/**").hasRole("ADMIN")
.antMatchers("/api/teacher/**").hasAnyRole("TEACHER", "ADMIN")
.antMatchers("/api/**").authenticated()
.anyRequest().permitAll()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
前端路由守卫实现:
javascript复制router.beforeEach((to, from, next) => {
const userRole = store.state.user.role;
const requiredRole = to.meta.role;
if (requiredRole && userRole !== requiredRole) {
next('/forbidden');
} else {
next();
}
});
推荐使用Docker Compose进行容器化部署:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: course_db
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
backend:
build: ./backend
ports:
- "8080:8080"
depends_on:
- mysql
frontend:
build: ./frontend
ports:
- "80:80"
volumes:
mysql_data:
java复制@Cacheable(value = "courses", key = "#root.methodName + '_' + #page + '_' + #size")
public Page<CourseVO> getCourseList(Integer page, Integer size) {
return courseMapper.selectPage(new Page<>(page, size), null);
}
sql复制ALTER TABLE t_course ADD INDEX idx_category_status (category_id, status);
ALTER TABLE t_learning_progress ADD INDEX idx_user_course (user_id, course_id);
注意:MySQL8.0默认的身份验证插件是caching_sha2_password,如果使用旧版客户端工具连接,需要在my.cnf中添加default_authentication_plugin=mysql_native_password。
问题1:Vue3前端访问SpringBoot跨域
解决方案:配置后端CORS过滤器
java复制@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
问题2:MyBatis-Plus分页失效
检查要点:
java复制@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
这套系统在实际教学场景中已经过验证,能够支撑日均10万+的学习访问量。我在部署过程中特别建议增加Nginx作为反向代理,并配置合理的缓存策略来应对课程资源的集中访问。对于有更高性能需求的场景,可以考虑将热点数据迁移到Redis集群中。