校园背景的项目系统,往往存在每年都要给学生更换年级的需求。此文章用于记录部分实现思路。

需求:
1.创建班级时仅选择学段与入学年份,不选择年级。
2.每年自动更新一次班级升年级。
3.升学至下一学段时,入学年份需要变更。

一、表设计与示例数据

1.study_section 学段表

字段名 字段类型 字段注释
section_id int 学段id
section_name vchar 学段名称
sort int 排序序号
gradeNum int 有效年级数

学段示例数据

学段id 学段名称 排序序号 有效年级数
1 小学 1 6
2 初中 2 3
3 高中 3 3

2.study_grade 年级表

字段名 字段类型 字段注释
grade_id int 年级id
section_id int 学段id
grade_name vchar 年级名称
sort int 排序序号

年级示例数据

年级id 学段id 年级名称 排序序号
1 1 一年级 1
2 1 二年级 2
3 1 三年级 3
4 1 四年级 4
5 1 五年级 5
6 1 六年级 5
7 1 未安排 6
8 1 已毕业 -1
9 2 初一 1
10 2 初二 2
11 2 初三 3
12 2 未安排 4
13 2 已毕业 -1
14 3 高一 1
15 3 高二 2
16 3 高三 3
17 3 未安排 4
18 3 已毕业 -1

3.study_class 班级表

字段名 字段类型 字段注释
class_id int 班级id
enrollment_year int 入学年份
grade_id int 年级id
class_num int 班号
class_name vchar 班级名称

班级示例数据 (当前是2022年10月)

班级id 入学年份 年级id 班号 班级名称
1 2022 1 1 2022级小学1班(一年级)
2 2019 3 1 2019级小学1班(三年级)
3 2020 2 2 2020级初中2班 (初三)
4 2021 2 4 2021级初中4班(初二)
5 2022 3 5 2022级高中5班 (高一)

二、逻辑代码

1.创建班级

不可存在同入学年份、同学段、同班号的班级

public void addClass(StudyClassDTO classDTO) {// 1.先根据入学年份、学段获取年级Long gradeId = getGradeIdBySectionAndYear(classDTO.getSectionId(), classDTO.getEnrollmentYear());// 2.判断入学年份、年级、班号是否存在重复数据QueryWrapper<StudyClass> queryCla = new QueryWrapper<>();queryCla.lambda().eq(StudyClass::getEnrollmentYear, classDTO.getEnrollmentYear());queryCla.lambda().eq(StudyClass::getClassNum, classDTO.getCalssNum());queryCla.lambda().eq(StudyClass::getGradeId, gradeId);List<StudyClass> classList = studyClassMapper.selectList(queryCla);if (CollectionUtils.isNotEmpty()) {throw new ServiceException("已存在同年份、同学段、同班号班级!");}// 3.插入数据StudyClass addClass = new StudyClass();BeanUtils.copy(classDTO, param);param.setGradeId(gradeId);studyClassMapper.insert(addClass);
}/*** 根据传入的年份、学段获取年级* 默认按传入年份的九月开始算有效学期*/public Long getGradeIdBySectionAndYear(Long sectionId, Integer enrollmentYear) {// 1.查询入学年份与当前年份的间隔年数// 获取当前年份、月份,不可传入今年之后的年份int nowYear = Calendar.getInstance().get(Calendar.YEAR);int yearNum = nowYear - enrollmentYear.intValue();   // 同年则为0// 判断入学年份是否正确,根据学段查询有效的年级范围QueryWrapper<StudySection> querySec = new QueryWrapper<>();querySec.lambda().eq(StudySection::getSectionId, sectionId);StudySection studeySection = studySectionMapper.selectOne(querySec);Integer gradeNum = studeySection.getGradeNum();if(yearNum < 0 || yearNum > gradeNum-1){throw new ServiceException("入学年份不正确!");}// 根据学段查询年级id数组querySec.lambda().orderByAsc(StudyGrade::getSort);List<StudyGrade> gradeList = studyGradeMapper.selectList(querySec)if (CollectionUtils.isEmpty(gradeList)) {throw new ServiceException("该学段下暂无年级信息!");}if(yearNum >= gradeList.size()-1){throw new ServiceException("该学生已经毕业!");}return gradeList.get(yearNum);}

2.自动升年级定时器

思路:计算出班级当前年级的下一级,并批量替换。毕业年级排序为-1

(1) 待升级班级对象

// 待升级班级对象
public class UpClassInfo {private Long classId;     //班级idprivate Long gradeId;     //年级idprivate Integer gradeNumber;  //班级当前年级排序 -1代表已毕业private Long sectionId;       // 学段idprivate Integer gradeNum;        // 学段的有效年级数}

(2)定时任务代码

public void upClassLevel() {List<StudyClass> updateClassList = new ArrayList<>();// 1. 查询当前有效的班级列表(含当前年级排序、当前年级学段有效年数)List<UpClassInfo> upClassList = {查询sql...};if (CollectionUtils.isNotEmpty(upClassList)) {// 2.查询各学段年级的学段、年级排序以及年级id对应MapMap<String, Long> sectionGradeMap = new HashMap<>();// 偷懒复用一下对象List<UpClassInfo> sectionGradeList = {查询sql...};if (CollectionUtils.isNotEmpty(sectionGradeList)) {sectionGradeMap  = sectionGradeList.stream().collect(Collectors.toMap(sg -> sg.getSectionId() + "_" + sg.getGradeNumber, UpClassInfo::getGradeId, (sg1, sg2) -> sg1));}for (UpClassInfo upClass : upClassList) {Integer nextGradeNumber = upClass.getGradeNumber();if (upClass.getGradeNumber() + 1 > upClass.getGradeNum) {// 如果班级当前的年级排序已超过学段年级数范围,则判断为毕业(排序为-1)nextGradeNumber = -1;} else {// 否则正常取下一级年级nextGradeNumber = nextGradeNumber + 1;}StudyClass updateClass = new StudyClass();updateClass.setClassId(upClass.getClassId());updateClass.setGradeId(sectionGradeMap.get(upClass.getSectionId() + "_" + -1));// 加入待更新班级列表updateClassList.add(updateClass);// 记录班级年级变更日志...}if (CollectionUtils.isNotEmpty(upateClassList)) {// 批量更新studyClass.updateBatch(upateClassList);}}
}

三、问题拓展

如果是含多个学段的学校应该如何处理?

基础教育学校包含:小学、初中、高中三个学段。部分学校含有多个学段。
查询学校关联的学段范围,如果有小学、初中、高中任意相邻学段(怎么样算相邻学段?),则不处理毕业?而是继续升学至下一学段的年级,并修改入学年份。
相邻学段:学段的排序相邻

Java - 校园类型系统班级升年级相关推荐

  1. 基于JAVA校园疫情防控系统(Springboot框架) 开题报告

      本科生毕业论文 基于Java(springboot框架)校园疫情防控系统 开题报告 学    院: 专    业: 计算机科学与技术 年    级: 学生姓名: 指导教师:   XXXX大学本科生 ...

  2. 基于JAVA校园教务排课系统(Springboot框架) 开题报告

      本科生毕业论文 基于Java框架springboot校园教务排课系统 开题报告 学    院: 专    业: 计算机科学与技术 年    级: 学生姓名: 指导教师:   XXXX大学本科生毕业 ...

  3. [附源码]计算机毕业设计JAVA校园征兵及退役复原管理系统

    [附源码]计算机毕业设计JAVA校园征兵及退役复原管理系统 项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe ...

  4. 计算机毕业设计Java校园闲置物品交易平台(系统+源码+mysql数据库+lw文档)

    计算机毕业设计Java校园闲置物品交易平台(系统+源码+mysql数据库+lw文档) 计算机毕业设计Java校园闲置物品交易平台(系统+源码+mysql数据库+lw文档) 本源码技术栈: 项目架构:B ...

  5. [附源码]计算机毕业设计JAVA校园二手交易平台的设计

    [附源码]计算机毕业设计JAVA校园二手交易平台的设计 项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(I ...

  6. 基于JAVA校园社团活动管理系统计算机毕业设计源码+系统+数据库+lw文档+部署

    基于JAVA校园社团活动管理系统计算机毕业设计源码+系统+数据库+lw文档+部署 基于JAVA校园社团活动管理系统计算机毕业设计源码+系统+数据库+lw文档+部署 本源码技术栈: 项目架构:B/S架构 ...

  7. 基于JAVA校园外卖系统Web端计算机毕业设计源码+系统+数据库+lw文档+部署

    基于JAVA校园外卖系统Web端计算机毕业设计源码+系统+数据库+lw文档+部署 基于JAVA校园外卖系统Web端计算机毕业设计源码+系统+数据库+lw文档+部署 本源码技术栈: 项目架构:B/S架构 ...

  8. 计算机毕业设计Java校园闲置物品交换平台系统(源码+系统+mysql数据库+Lw文档)

    计算机毕业设计Java校园闲置物品交换平台系统(源码+系统+mysql数据库+Lw文档) 计算机毕业设计Java校园闲置物品交换平台系统(源码+系统+mysql数据库+Lw文档) 本源码技术栈: 项目 ...

  9. java计算机毕业设计班级同学录网站源码+数据库+系统+lw文档+部署

    java计算机毕业设计班级同学录网站源码+数据库+系统+lw文档+部署 java计算机毕业设计班级同学录网站源码+数据库+系统+lw文档+部署 本源码技术栈: 项目架构:B/S架构 开发语言:Java ...

最新文章

  1. 面试:什么是序列化,怎么序列化,为什么序列化,反序列化会遇到什么问题,如何解决?...
  2. QPropertyAnimation实现游戏地图场景变换
  3. arduino黑线循迹小车程序_循迹小车:给我一条线,我能自己走完全程
  4. leetcode51 --- solveNQueens
  5. 4.4.5 清除变量内容
  6. 知识、经验的漏洞还有很多很多
  7. 错误:[IM002] [Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序 解决方法_QT
  8. 数字图像处理与Python实现-边缘检测-Roberts算子边缘检测
  9. 机器学习——数学建模应用
  10. 手把手教您国外如何充值支付宝/微信教程
  11. 阿里云服务器突发性能型和共享型哪个好
  12. Java三目运算符 (Ternary Operator ? :)
  13. 读源码学算法之Monte Carlo Tree Search
  14. 【Android】debug 状态下其签名文件 debug.keystore 相关(如何获得该文件,其密码,获取其sha1、MD5等)
  15. 09、IO流—File类与IO流
  16. webstorm 激活破解方法
  17. 1-Adversarial Learning for Semi-Supervised Semantic Segmentation
  18. 2016 最新开发者账号 · 邓白氏申请申请流
  19. julia系列1:介绍与安装
  20. Python基于YOLOv7的火灾检测系统(源码&教程)

热门文章

  1. ArcGIS基础:相同空间人口图层的人口数量字段转移至小区图层(核心:相交操作)及制作人口密度专题图
  2. 矢量图、位图、RGB、YUV、JPEG、PNG的理解
  3. sql语句--黄一家
  4. 网易云音乐搜索引擎 python+whoosh---(3)界面
  5. win10桌面能不能写待办事件清单?
  6. 中国大学生服务外包【A类】参赛感想与经验(东部赛区)
  7. Mysql项目 github_GitHub 项目推荐|中国5级行政区域mysql库|基础数据|字典数据...
  8. python的扩展控制鼠标
  9. 国开计算机应用技术形考任务4答案,国开计算机应用基础形考任务答案.pdf
  10. 使用插件Bootstrap Fileinput文件上传