当前位置: 首页 > news >正文

从零到一:手把手教你用SpringBoot+MyBatis搭建一个Tlias智能学习辅助系统后端(含完整SQL)

从零到一:手把手教你用SpringBoot+MyBatis搭建Tlias智能学习辅助系统后端

1. 项目概述与技术选型

Tlias智能学习辅助系统是一个面向教育机构的全栈式管理平台,采用前后端分离架构。本教程将聚焦后端系统的完整搭建过程,基于以下技术栈:

核心框架选择

  • SpringBoot 2.7.5:简化配置的微服务框架
  • MyBatis 3.5.9:轻量级ORM框架
  • Lombok:自动生成样板代码

数据库支持

  • MySQL 8.0:关系型数据库
  • PageHelper:MyBatis分页插件

安全与工具

  • JWT:无状态身份验证
  • 阿里云OSS:分布式文件存储
  • Fastjson:高效JSON处理
// 典型POM依赖配置示例 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.3.0</version> </dependency> </dependencies>

2. 数据库设计与初始化

2.1 核心表结构设计

-- 部门表 CREATE TABLE dept ( id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT '部门ID', name VARCHAR(10) NOT NULL UNIQUE COMMENT '部门名称', create_time DATETIME NOT NULL COMMENT '创建时间', update_time DATETIME NOT NULL COMMENT '修改时间' ) COMMENT '部门表'; -- 员工表 CREATE TABLE emp ( id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT '员工ID', username VARCHAR(20) NOT NULL UNIQUE COMMENT '用户名', password VARCHAR(32) DEFAULT '123456' COMMENT '密码', name VARCHAR(10) NOT NULL COMMENT '姓名', gender TINYINT UNSIGNED NOT NULL COMMENT '性别(1-男,2-女)', job TINYINT UNSIGNED COMMENT '职位类型', dept_id INT UNSIGNED COMMENT '部门ID', create_time DATETIME NOT NULL COMMENT '创建时间', update_time DATETIME NOT NULL COMMENT '修改时间' ) COMMENT '员工表'; -- 操作日志表 CREATE TABLE operate_log ( id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT '日志ID', operate_user INT UNSIGNED COMMENT '操作人ID', operate_time DATETIME COMMENT '操作时间', class_name VARCHAR(100) COMMENT '类名', method_name VARCHAR(100) COMMENT '方法名', method_params VARCHAR(1000) COMMENT '方法参数', cost_time BIGINT COMMENT '执行耗时(ms)' ) COMMENT '操作日志表';

2.2 数据初始化脚本

-- 初始化部门数据 INSERT INTO dept VALUES (1,'学工部',NOW(),NOW()), (2,'教研部',NOW(),NOW()); -- 初始化员工数据 INSERT INTO emp VALUES (1,'admin','123456','系统管理员',1,1,NOW(),NOW()), (2,'teacher1','123456','张老师',1,2,NOW(),NOW());

3. 项目架构设计

3.1 分层架构

com.itheima ├── config # 配置类 ├── controller # 控制层 ├── service # 业务层 ├── mapper # 数据访问层 ├── pojo # 实体类 ├── aspect # AOP切面 ├── exception # 异常处理 └── utils # 工具类

3.2 RESTful接口规范

操作类型HTTP方法URL示例说明
新增POST/depts创建部门
删除DELETE/depts/{id}删除指定部门
修改PUT/depts更新部门信息
查询GET/depts/{id}获取部门详情

4. 核心功能实现

4.1 部门管理模块

实体类设计

@Data @NoArgsConstructor @AllArgsConstructor public class Dept { private Integer id; private String name; private LocalDateTime createTime; private LocalDateTime updateTime; }

Mapper接口

@Mapper public interface DeptMapper { @Select("SELECT * FROM dept") List<Dept> list(); @Delete("DELETE FROM dept WHERE id = #{id}") void deleteById(Integer id); @Insert("INSERT INTO dept(name,create_time,update_time) " + "VALUES(#{name},#{createTime},#{updateTime})") void insert(Dept dept); }

Service实现

@Service @Transactional public class DeptServiceImpl implements DeptService { @Autowired private DeptMapper deptMapper; @Override public void delete(Integer id) { deptMapper.deleteById(id); } @Override public void add(Dept dept) { dept.setCreateTime(LocalDateTime.now()); dept.setUpdateTime(LocalDateTime.now()); deptMapper.insert(dept); } }

4.2 员工管理模块

分页查询实现

public PageBean page(Integer page, Integer pageSize) { // 设置分页参数 PageHelper.startPage(page, pageSize); // 执行查询 List<Emp> empList = empMapper.list(); Page<Emp> p = (Page<Emp>) empList; // 封装分页结果 return new PageBean(p.getTotal(), p.getResult()); }

条件查询SQL

<!-- EmpMapper.xml --> <select id="list" resultType="com.itheima.pojo.Emp"> SELECT * FROM emp <where> <if test="name != null and name != ''"> AND name LIKE CONCAT('%',#{name},'%') </if> <if test="gender != null"> AND gender = #{gender} </if> </where> ORDER BY update_time DESC </select>

5. 高级功能实现

5.1 JWT认证集成

JWT工具类

public class JwtUtils { private static String signKey = "tlias-secret"; private static Long expire = 3600000L; public static String generateJwt(Map<String, Object> claims){ return Jwts.builder() .addClaims(claims) .signWith(SignatureAlgorithm.HS256, signKey) .setExpiration(new Date(System.currentTimeMillis() + expire)) .compact(); } public static Claims parseJWT(String jwt){ return Jwts.parser() .setSigningKey(signKey) .parseClaimsJws(jwt) .getBody(); } }

登录拦截器

@Component public class LoginCheckInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 1. 获取请求头中的token String token = request.getHeader("token"); // 2. 校验token if(!StringUtils.hasLength(token)){ Result error = Result.error("NOT_LOGIN"); response.getWriter().write(JSON.toJSONString(error)); return false; } try { JwtUtils.parseJWT(token); } catch (Exception e){ Result error = Result.error("NOT_LOGIN"); response.getWriter().write(JSON.toJSONString(error)); return false; } return true; } }

5.2 文件上传与阿里云OSS集成

OSS配置类

@Data @Component @ConfigurationProperties(prefix = "aliyun.oss") public class AliOSSProperties { private String endpoint; private String accessKeyId; private String accessKeySecret; private String bucketName; }

文件上传服务

@Service public class UploadServiceImpl implements UploadService { @Autowired private AliOSSProperties aliOSSProperties; @Override public String upload(MultipartFile file) throws IOException { // 生成唯一文件名 String originalFilename = file.getOriginalFilename(); String extname = originalFilename.substring(originalFilename.lastIndexOf(".")); String objectName = UUID.randomUUID() + extname; // 创建OSSClient实例 OSS ossClient = new OSSClientBuilder() .build(aliOSSProperties.getEndpoint(), aliOSSProperties.getAccessKeyId(), aliOSSProperties.getAccessKeySecret()); try { // 上传文件 ossClient.putObject(aliOSSProperties.getBucketName(), objectName, file.getInputStream()); // 返回访问URL return "https://" + aliOSSProperties.getBucketName() + "." + aliOSSProperties.getEndpoint() + "/" + objectName; } finally { ossClient.shutdown(); } } }

6. 系统优化与最佳实践

6.1 AOP实现操作日志

日志切面

@Aspect @Component @Slf4j public class OperateLogAspect { @Autowired private OperateLogMapper operateLogMapper; @Autowired private HttpServletRequest request; @Around("@annotation(com.itheima.annotation.Log)") public Object recordLog(ProceedingJoinPoint joinPoint) throws Throwable { long begin = System.currentTimeMillis(); // 执行原始方法 Object result = joinPoint.proceed(); long end = System.currentTimeMillis(); // 记录操作日志 OperateLog operateLog = new OperateLog(); operateLog.setCostTime(end - begin); operateLogMapper.insert(operateLog); return result; } }

6.2 全局异常处理

@RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public Result handleException(Exception e){ log.error("系统异常:", e); return Result.error("操作失败"); } @ExceptionHandler(SQLIntegrityConstraintViolationException.class) public Result handleSQLException(SQLIntegrityConstraintViolationException e){ String message = e.getMessage(); if(message.contains("Duplicate entry")){ return Result.error("数据已存在"); } return Result.error("数据库操作异常"); } }

7. 项目部署与测试

7.1 多环境配置

# application-dev.yml (开发环境) spring: datasource: url: jdbc:mysql://localhost:3306/tlias_dev username: dev_user password: dev123 # application-prod.yml (生产环境) spring: datasource: url: jdbc:mysql://prod-db:3306/tlias_prod username: prod_user password: prod@123

7.2 接口测试示例

部门列表查询测试

GET /depts HTTP/1.1 Host: localhost:8080 Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...

响应示例

{ "code": 1, "msg": "success", "data": [ { "id": 1, "name": "学工部", "createTime": "2023-07-20T10:00:00", "updateTime": "2023-07-20T10:00:00" } ] }

8. 性能优化建议

  1. 缓存策略:集成Redis缓存热点数据
  2. SQL优化:为常用查询字段添加索引
  3. 异步处理:使用@Async处理耗时操作
  4. 连接池配置:调整Druid连接池参数
  5. JVM调优:根据服务器配置调整JVM参数
// 异步处理示例 @Async public void asyncProcess() { // 耗时操作 }

通过本教程,我们完整实现了Tlias智能学习辅助系统的后端开发,涵盖了从基础CRUD到高级功能的全面解决方案。实际开发中可根据业务需求进行扩展,如增加消息队列、分布式锁等机制应对更复杂的业务场景。

http://www.jsqmd.com/news/554415/

相关文章:

  • NLP-StructBERT在对话系统中的应用:提升意图识别与上下文理解
  • 2026年浙江废轮胎裂解炼油设备制造商年度排名,性价比高的有几家 - mypinpai
  • 如何用5分钟解决联想拯救者BIOS限制?这个工具让你轻松访问隐藏设置
  • OpenClaw深度沟通渠道-全景深度解构
  • 突破性AI开发工具Get Shit Done:上下文衰退的核心解决方案
  • 微信聊天记录永久保存与深度分析解决方案:跨平台数据管理工具WeChatMsg全指南
  • 694738
  • ROS2实时性能“体检”指南:用LTTng和cyclictest给你的机器人系统做一次深度性能剖析
  • 2026年纸包鱼火锅批量加盟品牌费用多少,河南企业性价比排名 - 工业品网
  • JavaScript前端动态交互:Streamlit结合Nanbeige 4.1-3B实现实时AI响应
  • Qwerty Learner终极指南:免费提升英语打字速度的完整教程
  • (Javascript)动态抠像:AI数字人视频转Canvas并实时去绿幕技术解析
  • 造相-Z-Image-Turbo 在企业CRM系统的应用:自动生成客户虚拟形象
  • 保姆级教程:用闲置的S905L3B机顶盒刷Armbian,5分钟搞定中文环境与清华源配置
  • PFC直剪试验:当岩石遇上浆液的暴力美学
  • 纸包鱼火锅加盟品牌怎么选,河南永邦餐饮在河南区域值得考虑吗 - 工业品牌热点
  • Qwen3-VL-8B-Instruct-GGUF保姆级部署教程:5分钟在MacBook上跑通视觉问答
  • Phi-3-Mini-128K赋能微信小程序:打造轻量级AI工具应用
  • DC/DC模块选型避雷指南:如何通过规格书预判纹波性能?
  • gVim 界面美化与基础配置避坑指南:从 syntax on 到 colorscheme 的每一步详解
  • 三步掌握全平台弹幕抓取:从技术原理到实战应用
  • java毕业设计基于springboot+vue的甘肃睿达公司人力资源管理系统
  • 保姆级教程:在Win10上用CMake编译带Contrib模块的OpenCV 4.12.0,适配VS2026和Qt 6.9
  • PathOfBuilding:流放之路角色构建的科学决策工具
  • CompressO:重新定义视频压缩的开源解决方案
  • 别再让VRRP频繁震荡!深度解析华为MSTP配置如何影响网关冗余稳定性
  • 从硬件工程师视角看STM32WB55:自己画板子踩过的那些坑(含DAP下载器烧芯片实录)
  • 探讨2026年售后完善的财务服务机构,株洲瀚通金融费用透明靠谱 - myqiye
  • 分析昆明不错的企业AI服务机构,怎么选择 - 工业设备
  • KART-RERANK模型与LaTeX文档智能编排系统的结合