初中语数英答题与竞赛平台

文章目录

  • 后端类职责说明
    • 一、整体结构与阅读顺序
    • [二、每个 Java 类的职责](#二、每个 Java 类的职责)
      • [1. 启动与配置:2 个类](#1. 启动与配置:2 个类)
      • [2. 登录注册与身份认证:5 个类](#2. 登录注册与身份认证:5 个类)
      • [3. 通用响应、异常和规则:7 个类](#3. 通用响应、异常和规则:7 个类)
      • [4. 管理员用户管理与个人中心:2 个类](#4. 管理员用户管理与个人中心:2 个类)
      • [5. 题库、练习与错题本:2 个类](#5. 题库、练习与错题本:2 个类)
      • [6. 试卷管理、在线考试与成绩:3 个类](#6. 试卷管理、在线考试与成绩:3 个类)
      • [7. 竞赛中心:1 个类](#7. 竞赛中心:1 个类)
      • [8. 积分与奖品商城:2 个类](#8. 积分与奖品商城:2 个类)
      • [9. 工作台与学情分析:3 个类](#9. 工作台与学情分析:3 个类)
    • [三、内部 record 对象是做什么的](#三、内部 record 对象是做什么的)
    • 四、核心业务链路
      • [1. 登录与鉴权](#1. 登录与鉴权)
      • [2. 学生考试](#2. 学生考试)
      • [3. 学生竞赛](#3. 学生竞赛)
      • [4. 错题复习](#4. 错题复习)
      • [5. 积分兑换](#5. 积分兑换)
      • [6. 管理员维护用户](#6. 管理员维护用户)
    • 五、主要数据库表与代码对应关系
    • 六、答辩可讲的重点与难点

后端类职责说明

本文依据 primary-school-backend/src/main/java/com/primary 的现有实现编写,覆盖全部 27 个 Java 主源码文件,并补充内部请求对象、核心业务流程和毕业设计答辩重点。

一、整体结构与阅读顺序

系统面向初中七、八、九年级,包含管理员、教师、学生三类角色。后端使用 Spring Boot 提供 HTTP 接口,以 JdbcTemplate 访问 MySQL,以 R<T> 返回统一的 code、msg、data 结构。

当前项目实际采用"Controller + JdbcTemplate + 部分公共 Service + 工具类"的结构。多数 Controller 同时处理接口、业务校验和 SQL;积分、错题本和 JWT 的通用逻辑已分别抽到 Service。当前主源码中没有独立的 Entity、Mapper 或 Repository 层,不能在论文中把尚未实现的完整三层结构描述为已有设计。

类型 当前承担的职责 代表类
启动类 创建 Spring 容器、启动 Web 服务、扫描组件 PrimarySchoolApplication
Controller 定义接口、接收参数、检查业务权限、组织业务流程和返回数据;多数类还直接执行 SQL AuthController、ExamController 等
Service 复用跨模块业务规则或认证能力 PointService、WrongBookService、JwtService
认证支撑 解析请求身份、读取当前用户、进行角色校验 AuthFilter、CurrentUser、LoginUser
工具与异常 共享权限、时间、判分、年级规则,统一错误响应 ApiSupport、ExamDeadline、ObjectiveJudge、GradeRules 等
配置类 注册密码组件、跨域规则、头像资源映射及启动初始化 AppConfig
内部 record 表达请求、计算结果或 SQL 参数片段,不是持久化实体 各 Controller 内部请求对象、AwardResult 等

建议阅读顺序:启动和配置 → 认证 → 公共响应及权限 → 题库 → 试卷和考试 → 竞赛 → 错题与积分 → 奖品 → 学情统计。

二、每个 Java 类的职责

以下路径均相对于 primary-school-backend/src/main/java/com/primary。

1. 启动与配置:2 个类

类及路径 作用 关键机制与协作
PrimarySchoolApplication:PrimarySchoolApplication.java 项目启动入口,执行 SpringApplication.run @SpringBootApplication 默认从 com.primary 向下扫描,发现控制器、服务、配置和过滤器
AppConfig:config/AppConfig.java 注册 BCrypt 编码器,配置跨域和头像静态目录,空用户表时补建基础演示账号 CommandLineRunner 只初始化基础账号及班级关系,不负责建表或完整演示数据;/uploads/** 映射到运行目录的 uploads 文件夹

跨域解决浏览器是否允许读取 API 响应;接口权限仍由认证和业务校验决定。启动初始化中的异常会被捕获,应用启动成功不等于数据库已正确初始化。

2. 登录注册与身份认证:5 个类

类及路径 作用 关键机制与协作
AuthController:auth/AuthController.java 登录、学生公开注册、算术验证码、当前用户查询和退出登录 查询 sys_user、学生及教师班级关系;登录使用 BCrypt 校验并调用 JwtService;注册固定创建 STUDENT,并在事务中保存学生班级
AuthFilter:auth/AuthFilter.java 在控制器之前处理 Bearer Token,恢复本次请求身份 调用 JwtService.parse 验签,再按用户 ID 回查启用账号,将实时身份写入请求属性;失效或禁用账号不恢复身份
JwtService:auth/JwtService.java 生成、验证 HS256 JWT 使用服务端密钥签名,验证格式、签名和有效期;JWT 编码不保密,不能存放密码;载荷中的角色不作为最终实时权限依据
CurrentUser:auth/CurrentUser.java 获取当前请求用户,提供管理员、教师和学生角色入口校验 从 RequestContextHolder 的请求属性读取身份;teacher() 允许管理员,具体学科与班级权限还需业务层继续检查
LoginUser:auth/LoginUser.java 以不可变 record 表达当前用户基本身份 包含 ID、用户名、姓名、角色、年级、任教学科,提供 isAdmin/isTeacher/isStudent;不包含密码和联系方式

主要入口:POST /api/auth/login、POST /api/auth/register、GET /api/auth/captcha、GET /api/auth/me。

验证码保存在内存,使用 ConcurrentHashMap.remove 原子消费,5 分钟有效且只能使用一次。即使后续注册因用户名重复而失败,数据库回滚也不会恢复内存验证码。该机制适用于当前单进程部署,不能描述为跨实例共享验证码。

退出登录接口不在服务端建立 JWT 黑名单,当前流程由前端清除本地令牌。账号禁用或删除会通过每次请求回查即时影响后续访问。

3. 通用响应、异常和规则:7 个类

类及路径 作用 关键机制与协作
R<T>:common/R.java 统一成功和失败响应,包含 code、msg、data ok 返回业务码 200,fail/error 返回失败信息;JSON 业务码与 HTTP 状态码是不同概念
BizException:common/BizException.java 表达可预期的参数、权限或状态错误 携带业务错误码和用户可读消息,继承运行异常,可触发 Spring 默认事务回滚
GlobalExceptionHandler:common/GlobalExceptionHandler.java 将业务异常、参数绑定异常、数据库约束异常和未知异常转换为统一响应 查找 JSON 反序列化异常的 cause 链,保留 record 构造器的业务提示;未知异常记录日志,不向客户端返回堆栈
ApiSupport:common/ApiSupport.java 共享 JDBC 行查询、字段转换、创建者权限及学科/年级/班级校验 教师权限匹配"年级+班级"组合;学生班级从关系表实时读取;one 取第一行,查询唯一性由主键、唯一键及调用方保证
ObjectiveJudge:common/ObjectiveJudge.java 统一练习、考试和竞赛的客观题判分 单选忽略大小写,多选集合完全一致且拒绝重复项,判断按文本匹配,填空命中任一可接受答案;正确满分、错误零分
GradeRules:common/GradeRules.java 集中维护年级顺序、下一年级及练习积分范围 当前年级及下一年级属于可积分范围;九年级没有下一年级;实际发分还需检查首次答对、错题模式及每日额度
ExamDeadline:exam/ExamDeadline.java 计算学生个人考试截止时间 返回 min(started_at + duration_minutes, end_time);包级工具,由 ExamController 统一调用,无数据库读写

ExamDeadline 位于考试包,但属于纯计算工具。本节归入共享机制说明,后续考试模块不重复计数。

4. 管理员用户管理与个人中心:2 个类

类及路径 作用 关键机制与协作
UserController:user/UserController.java 管理员创建、查询、修改账号和删除非管理员用户 使用 sys_user、student_class_assignment、teacher_class_assignment;创建和更新在事务中完成主表及班级关系,修改角色时清除旧关系再重建
ProfileController:user/ProfileController.java 当前用户查询和维护个人资料、修改用户名或密码、上传头像 用户 ID 取自登录身份;姓名与身份信息由管理员维护;修改用户名仅传新用户名,修改密码仍校验原密码;头像文件存磁盘、URL 存数据库

主要入口:/api/admin/users、/api/profile、PUT /api/profile/username、PUT /api/profile/password、POST /api/profile/avatar。

修改用户名后用户 ID 不变,JWT 仍通过 ID 查到账号,后续请求回查新用户名。唯一用户名既有应用查重,也有数据库唯一约束保护并发写入。

头像上传检查大小、声明 MIME 类型、扩展名和最终路径,没有进行图片解码内容鉴别。磁盘写文件与数据库更新也不是同一个可自动回滚的事务。

5. 题库、练习与错题本:2 个类

类及路径 作用 关键机制与协作
QuestionController:question/QuestionController.java 教师题库筛选、分页、随机抽题、录题、修改、删除和审核;学生练习、查询最近作答和错题入口 使用 quiz_question、practice_record,复用 ObjectiveJudge、PointService、WrongBookService;批量录题最多 20 道且整批回滚
WrongBookService:question/WrongBookService.java 维护错题状态,补齐历史错题,提供当前错题和已掌握历史 使用 wrong_question_state;答错进入 IN_BOOK,复习答对进入 READY_TO_REMOVE,学生确认进入 MASTERED;再次答错可重新进入错题本

主要入口:/api/teacher/questions、/api/student/questions、POST /api/student/questions/{id}/practice、/api/student/wrong-book。

随机抽题的比例模式使用最大余数法分配整数题数,再按难度抽取,题量不足时从其他难度补齐。因此返回的实际难度比例可能不同于目标比例,接口会给出相应提示。

普通自主练习只开放公开、审核通过、用途为 PRACTICE 的当前或下一年级题。当前错题允许继续复习,即使题目不再满足普通练习列表条件;错题复习不奖励积分。

历史错题同步使用三类来源的 UNION ALL,按题目统计后 INSERT IGNORE 补建缺失状态。它不会每次打开错题本都重复累计旧错误,也不会用历史数据覆盖已掌握状态。

6. 试卷管理、在线考试与成绩:3 个类

类及路径 作用 关键机制与协作
PaperController:paper/PaperController.java 教师创建和修改试卷,维护题目分值、目标班级、开放时间,发布或取消发布,删除试卷 使用 quiz_paper、quiz_paper_question、quiz_paper_target_class;新建先保存 DRAFT,发布前要求题目公开且审核通过;已开始的发布试卷禁止修改
ExamController:exam/ExamController.java 学生考试列表、开始/恢复、答案保存、提交判分、成绩和逐题详情 使用 quiz_record、quiz_answer;保存和交卷先锁答卷;使用 ExamDeadline;交卷调用判分、错题和积分服务,直接完成客观题 GRADED 状态
GradingController:grading/GradingController.java 教师和管理员读取考试成绩及答题明细 列表按已完成状态查询,普通教师限制任教学科及试卷创建人;详情再检查学生班级范围;当前没有人工修改分数接口

主要入口:/api/teacher/papers、/api/student/exams、/api/student/records/{recordId}、POST /api/student/records/{recordId}/submit、/api/teacher/grading。

试卷内题目分值来自 quiz_paper_question.score,不应混用题库中的默认 quiz_question.score。一张题库题目可以在不同试卷中设置不同分值。

考试详情新增的 effectiveEndTime 表示个人有效截止;startTime/endTime 仍表示试卷开放窗口。标准答案与解析只在 SUBMITTED/GRADED 状态返回,进行中的答卷在 SQL 层置空答案字段。

7. 竞赛中心:1 个类

类及路径 作用 关键机制与协作
ContestController:contest/ContestController.java 学生查竞赛、报名、开始、保存、提交、查榜;教师维护竞赛、目标班级、题目和查看结果 使用竞赛主表及五张关系/记录表;报名前检查发布和开始时间;开始要求已报名;交卷锁答卷,客观题自动判分后写错题和积分

主要入口:/api/contests、POST /api/contests/{id}/register、POST /api/contests/{id}/start、PUT /api/contests/{id}/answers、POST /api/contests/{id}/submit、GET /api/contests/{id}/ranking、/api/teacher/contests。

竞赛报名记录表示资格,答题记录表示实际参与,不能用报名人数代替完成参赛人数。已有学生报名后禁止改变面向年级或班级;竞赛已开始后禁止编辑。

当前竞赛使用全局 start_time/end_time 控制答题窗口,没有套用考试的个人 effectiveEndTime。duration_minutes 在请求缺省结束时间时参与生成 end_time,不能把它描述为当前竞赛已实现的个人倒计时上限。

排行榜在竞赛结束且学生已提交后可查看,依次按总分降序、用时升序、提交时间升序、记录 ID 升序排序。ROW_NUMBER 产生唯一连续名次,班级筛选后重新计算筛选范围内排名。

8. 积分与奖品商城:2 个类

类及路径 作用 关键机制与协作
PointService:point/PointService.java 计算积分余额、当天剩余额度,按业务来源幂等发放学习积分 使用 student_point_log;余额为全部正负流水之和;学习奖励每日最多 120 分;锁学生用户行后查重、计算额度并写流水
RewardController:reward/RewardController.java 学生浏览奖品及申请兑换,教师维护奖品和处理兑换,管理员审核奖品 使用 point_reward、point_redeem_record、student_point_log;申请不预扣资源,通过兑换审核时锁记录并扣库存、写负积分流水;创建者每月预算 500 分

主要入口:/api/student/rewards、/api/teacher/rewards、/api/admin/rewards/{id}/approve、/api/teacher/redeem-records。

积分来源主键有明确约定:PRACTICE 使用题目 ID,EXAM 使用答卷 ID,CONTEST 使用竞赛 ID,REDEEM 使用兑换申请 ID。来源编号需要与学生 ID、来源类型一起判断,不能独立解释。

PointService.awardLearningPoints 自身没有 @Transactional,由练习、考试、竞赛事务接口调用。用户行锁依赖外层事务覆盖"查重、额度计算、插流水"全过程。实际奖励为零也记录流水,防止同一来源在次日重复领取。

商城有两个不同状态维度:奖品的 approval_status 表示管理员内容审核,奖品的 status 表示上下架;兑换申请的 status 表示教师处理学生申请的结果。二者不能混为同一种审核。

9. 工作台与学情分析:3 个类

类及路径 作用 关键机制与协作
DashboardController:dashboard/DashboardController.java 按角色返回首页数量、趋势、学生积分、近期成绩、竞赛及待办 管理员全量统计,教师按本人和学科统计,学生按本人统计;待办按考试、竞赛、练习顺序最多返回 6 条,路径沿用已有前端路由
StudentAnalysisController:analysis/StudentAnalysisController.java 学生作答概览、分学科与题型正确率、最近六次考试趋势 三类学习来源使用 UNION ALL 合并;固定分类左连接补零;作答次数不是去重题数;趋势先取最近六条再正序显示
TeacherAnalysisController:analysis/TeacherAnalysisController.java 普通教师任教班级概览、知识点正确率和班级学生排名 allowed CTE 固定任教范围,学科参数限制教学内容;合并考试和竞赛为百分制得分率;不包含普通练习;管理员不进入此个人任教统计接口

主要入口:/api/dashboard/admin、/api/dashboard/teacher、/api/dashboard/student、/api/student/analysis、/api/teacher/analysis。

教师班级均分先算每个学生的平均得分率,再按班级平均,每位参测学生权重一致;及格与优秀分别以 60、85 为阈值。统计依据学生当前班级,未建立历史班级快照,不能描述为按参加测评时的历史班级统计。

学生综合正确率按"正确作答次数 / 总作答次数"计算。教师班级均分、学生正确率和考试得分率是不同口径,论文应分别说明。

以上主源码计数:2 + 5 + 7 + 2 + 2 + 3 + 1 + 2 + 3 = 27,其中 ExamDeadline 只计一次。

三、内部 record 对象是做什么的

这些类型定义在所属 Java 文件内,不对应数据库表,主要用于 JSON 参数绑定、结果表达和字段整理。

所属类 内部对象 用途
AuthController LoginRequest、RegisterRequest 登录和学生注册参数,构造时完成必填及角色等基础校验
AuthController CaptchaItem 保存服务端验证码正确答案和过期时间,不返回给前端
UserController UserRequest、UpdateUserRequest 管理员新建和修改账号的参数;修改请求不包含密码
UserController TeachingAssignment、UserFields 表达任教班级以及按角色归一化后的账号字段
ProfileController ProfileRequest、UsernameRequest、PasswordRequest 联系资料、新用户名、旧密码与新密码确认参数
QuestionController PracticeRequest、BatchQuestionRequest、QuestionRequest 自主练习答案、批量录题列表、单题定义
QuestionController QueryParts 将动态 SQL 片段与按顺序绑定的参数放在一起,供多个查询复用
PaperController PaperRequest、QuestionItem 试卷配置及题目 ID、顺序、试卷内分值
ExamController AnswerRequest、AnswerItem 批量考试答案及单题编号、答案文本
ContestController AnswerRequest、AnswerItem、QuestionItem、ContestRequest 竞赛答案、组题与竞赛基本配置;与考试请求名称相似但分别属于不同类
PointService AwardResult 实际发放分数、是否重复、总余额及每日剩余额度
WrongBookService WrongBookUpdate 错题状态、练习次数、错误次数、连续答对次数及是否可以移出
RewardController RewardRequest、ReviewRequest 奖品配置及可选审核备注

record 的紧凑构造器在 JSON 反序列化时执行。构造器负责默认值及不依赖数据库的基础校验,数据库权限、唯一性和状态校验仍由业务方法执行。

四、核心业务链路

1. 登录与鉴权

  1. 前端提交用户名、密码,AuthController 查询启用账号并通过 BCrypt 验证。
  2. JwtService 按用户 ID 等字段生成有时限的签名令牌,接口返回令牌和脱敏资料。
  3. 后续请求携带 Authorization: Bearer ...,AuthFilter 验证令牌后回查账号实时状态。
  4. CurrentUser 读取本次请求身份并校验角色;各业务接口再校验数据创建者、任教学科或班级范围。
  5. 业务成功返回 R.ok;失败抛出 BizException 或由全局处理器转换统一失败响应。

2. 学生考试

  1. 教师保存草稿试卷,配置题目、试卷内分值、目标班级和开放窗口,发布前校验题目审核状态。
  2. 学生在本人年级班级范围内查看考试,在开放窗口内调用开始接口。
  3. 首次创建 IN_PROGRESS 答卷并保存 started_at,重复进入复用唯一答卷和原开始时间。
  4. 详情返回 effectiveEndTime = min(started_at + duration_minutes, end_time),刷新页面不重新计时。
  5. 自动保存先锁答卷,再检查状态、个人截止时间及题目归属,使用唯一键新增或覆盖答案。
  6. 手动或超时提交先锁答卷;截止前接受请求中的答案,截止后仅结算服务端已保存答案。
  7. 补齐未答题空记录,按 ObjectiveJudge 判分,写错题,更新总分和 GRADED 状态。
  8. 以答卷 ID 为积分来源发奖,及格得 10 分、否则 5 分,实际发放受每日额度约束。
  9. 事务整体提交后返回成绩;重复交卷读取既有结果,不再次判分或发奖。

3. 学生竞赛

  1. 教师配置竞赛、目标班级和题目,发布时校验题目公开且审核通过。
  2. 学生必须在竞赛开始前报名,报名唯一约束防止重复报名。
  3. 开始后、结束前且已报名的学生可创建或恢复答卷,答卷保留实际开始时间。
  4. 在竞赛全局窗口内保存答案,交卷锁定记录并按是否过截止决定是否接受新答案。
  5. 判分、写错题、计算有效用时、更新 SUBMITTED 状态和积分流水在同一事务中完成。
  6. 有得分请求奖励 20 分,零分请求奖励参与分 10 分,实际发放仍受每日上限约束。
  7. 竞赛结束后,已提交学生按成绩与用时等条件查看排行榜。

4. 错题复习

  1. 普通练习、考试或竞赛判错时记录错题,重复答错累加次数并保持或重新进入 IN_BOOK。
  2. 查询错题本时补齐缺失的历史错题状态,保留已有复习成果。
  3. 当前错题复习答对后进入 READY_TO_REMOVE,界面可以展示"可移出"状态。
  4. 学生确认移出后更新为 MASTERED,历史错误与练习记录继续保留。
  5. 错题复习不奖励积分;再次答错时重新进入 IN_BOOK。

5. 积分兑换

  1. 教师创建奖品后进入待管理员审核且下架状态,管理员通过后有库存才上架。
  2. 学生浏览可用奖品,接口附带余额差额和创建者预算信息。
  3. 学生申请兑换时检查条件并保存 PENDING,不立即扣积分或库存,也不预占资源。
  4. 教师处理本人奖品申请,管理员可处理全部;先锁申请,确认仍处于待审核。
  5. 同意时锁学生、奖品创建者和奖品,重新验证余额、月预算和库存。
  6. 扣库存、必要时下架、写 REDEEM 负积分流水、更新 APPROVED 及审核信息,事务共同提交。
  7. 拒绝时只更新 REJECTED 与审核备注,无需退分或回补库存,因为申请阶段没有扣减。

6. 管理员维护用户

  1. 管理员接口首先校验 ADMIN 身份,公共学生注册不能创建教师或管理员。
  2. 创建用户时加密初始密码,按角色保存学生班级或教师任教关系。
  3. 修改角色或班级时更新主表、删除旧关系、重建新关系,事务保证三者一致。
  4. 禁用或删除账号后,认证过滤器回查时不再恢复其身份。
  5. 所有 ADMIN 账号均禁止通过当前删除接口删除,防止丢失管理入口。

五、主要数据库表与代码对应关系

业务 表 主要读写类
用户与班级 sys_user、student_class_assignment、teacher_class_assignment AuthController、AuthFilter、UserController、ProfileController、ApiSupport
题库 quiz_question QuestionController,试卷、竞赛、错题和统计模块也读取
试卷配置 quiz_paper、quiz_paper_target_class、quiz_paper_question PaperController,ExamController 和统计模块读取
考试作答 quiz_record、quiz_answer ExamController,GradingController、错题及统计模块读取
普通练习 practice_record QuestionController,错题与统计模块读取
错题状态 wrong_question_state WrongBookService
竞赛配置 contest、contest_target_class、contest_question ContestController,首页和统计模块读取
竞赛参与 contest_registration、contest_record、contest_answer ContestController,错题与统计模块读取
积分流水 student_point_log PointService、RewardController,首页读取
奖品与兑换 point_reward、point_redeem_record RewardController,首页读取审核数量

表组覆盖 20 张业务表。年级与班级组成业务范围,关系表保存的是年级、班级名称及用户或测评主键,不应描述为另有独立班级实体表。

六、答辩可讲的重点与难点

重点 清晰解释 代码位置
实时身份与角色权限 JWT 验证身份标识,数据库回查保证禁用、改名和角色变更及时生效;角色进入权限与数据范围权限分开检查 JwtService、AuthFilter、CurrentUser、ApiSupport
密码存储 BCrypt 保存不可逆哈希,校验通过 matches;随机盐使同一明文的不同编码结果不必相同 AuthController、ProfileController、AppConfig
个人考试计时 开放窗口允许学生进入的时间与每位学生答题时长不同,取两个截止时间的较早者并保留原始开始时间 ExamDeadline、ExamController
幂等提交 锁定答卷后检查完成状态,重复请求返回既有结果,避免二次判分、错题计数和积分 ExamController.submit、ContestController.submit
多表事务 判分、错题、成绩和积分一起成功或回滚;兑换的库存、扣分和状态也一起提交 各核心接口的 @Transactional
行锁与唯一约束 行锁协调并发的读后写流程,唯一键防止重复记录,事务覆盖锁的有效期;单有注解不等于天然消除所有竞争 答卷读取、积分用户锁、奖品审核、答案 UPSERT
自增主键取得 last_insert_id() 是连接级状态,需要插入和主键查询复用连接,不能用全表最大 ID 代替 注册、用户创建、组卷、竞赛创建和录题
错题状态 待复习、答对待移出、已掌握是明确状态;移出保留历史,再次答错可重新进入 WrongBookService
统一判分 三个业务入口复用一套规则;多选忽略顺序却拒绝重复,填空只匹配可接受答案,不实现语义判分 ObjectiveJudge
学习积分防重复 来源类型和来源 ID 定义清晰,用户锁保护每日额度,零分流水也表示该来源已经处理 PointService
两阶段兑换 申请不占资源,通过时再次检查并扣资源,拒绝只更新状态 RewardController
统计口径与 SQL 保留重复作答用 UNION ALL,补零用固定分类加 LEFT JOIN,防除零用 NULLIF,排名用窗口函数 两个 AnalysisController、DashboardController

@Transactional 默认在经 Spring 代理的外部方法调用中生效。当前事务接口内部调用辅助方法会沿用已有事务,不应解释为每个内部方法自动创建独立事务。默认对运行异常回滚,BizException 符合该规则;文件系统和内存验证码不受数据库事务自动回滚控制。

相关推荐
知守观1 小时前
一个半天需求干了三天:代码腐化的五个信号与自查命令
java·后端·代码规范
代码山河1 小时前
Java学习路线图:2026年最新版,从入门到架构师
java·学习·架构·教程·面向对象·项目
落日归屿1 小时前
AI 商品图做完后,为什么还要管图层?
数据库
anew___1 小时前
《从零手写操作系统 (30):环境变量与进程上下文——export/unset与继承语义》
java·开发语言·网络·jvm·算法
jason成都1 小时前
rtklib_java项目新增模块:rtklib-research与rtklib-stream功能详解
java·gnss·rtklib·rtklib_java
拾贰_C1 小时前
【English | conversation 】call | 抖音AI短句情景:打电话---come over
数据库·redis·缓存
2601_962885721 小时前
AlphaFeed 支持哪些 K 线周期?period参数怎么传?
前端·数据库·python
endswel2 小时前
Spring bean 注册多种方式
java·后端·spring
鬼手点金2 小时前
opencode-性能优化建议
java·人工智能·git·自动化·nanogpt