Java - 校园类型系统班级升年级
校园背景的项目系统,往往存在每年都要给学生更换年级的需求。此文章用于记录部分实现思路。
需求:
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 - 校园类型系统班级升年级相关推荐
- 基于JAVA校园疫情防控系统(Springboot框架) 开题报告
本科生毕业论文 基于Java(springboot框架)校园疫情防控系统 开题报告 学 院: 专 业: 计算机科学与技术 年 级: 学生姓名: 指导教师: XXXX大学本科生 ...
- 基于JAVA校园教务排课系统(Springboot框架) 开题报告
本科生毕业论文 基于Java框架springboot校园教务排课系统 开题报告 学 院: 专 业: 计算机科学与技术 年 级: 学生姓名: 指导教师: XXXX大学本科生毕业 ...
- [附源码]计算机毕业设计JAVA校园征兵及退役复原管理系统
[附源码]计算机毕业设计JAVA校园征兵及退役复原管理系统 项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe ...
- 计算机毕业设计Java校园闲置物品交易平台(系统+源码+mysql数据库+lw文档)
计算机毕业设计Java校园闲置物品交易平台(系统+源码+mysql数据库+lw文档) 计算机毕业设计Java校园闲置物品交易平台(系统+源码+mysql数据库+lw文档) 本源码技术栈: 项目架构:B ...
- [附源码]计算机毕业设计JAVA校园二手交易平台的设计
[附源码]计算机毕业设计JAVA校园二手交易平台的设计 项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(I ...
- 基于JAVA校园社团活动管理系统计算机毕业设计源码+系统+数据库+lw文档+部署
基于JAVA校园社团活动管理系统计算机毕业设计源码+系统+数据库+lw文档+部署 基于JAVA校园社团活动管理系统计算机毕业设计源码+系统+数据库+lw文档+部署 本源码技术栈: 项目架构:B/S架构 ...
- 基于JAVA校园外卖系统Web端计算机毕业设计源码+系统+数据库+lw文档+部署
基于JAVA校园外卖系统Web端计算机毕业设计源码+系统+数据库+lw文档+部署 基于JAVA校园外卖系统Web端计算机毕业设计源码+系统+数据库+lw文档+部署 本源码技术栈: 项目架构:B/S架构 ...
- 计算机毕业设计Java校园闲置物品交换平台系统(源码+系统+mysql数据库+Lw文档)
计算机毕业设计Java校园闲置物品交换平台系统(源码+系统+mysql数据库+Lw文档) 计算机毕业设计Java校园闲置物品交换平台系统(源码+系统+mysql数据库+Lw文档) 本源码技术栈: 项目 ...
- java计算机毕业设计班级同学录网站源码+数据库+系统+lw文档+部署
java计算机毕业设计班级同学录网站源码+数据库+系统+lw文档+部署 java计算机毕业设计班级同学录网站源码+数据库+系统+lw文档+部署 本源码技术栈: 项目架构:B/S架构 开发语言:Java ...
最新文章
- 面试:什么是序列化,怎么序列化,为什么序列化,反序列化会遇到什么问题,如何解决?...
- QPropertyAnimation实现游戏地图场景变换
- arduino黑线循迹小车程序_循迹小车:给我一条线,我能自己走完全程
- leetcode51 --- solveNQueens
- 4.4.5 清除变量内容
- 知识、经验的漏洞还有很多很多
- 错误:[IM002] [Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序 解决方法_QT
- 数字图像处理与Python实现-边缘检测-Roberts算子边缘检测
- 机器学习——数学建模应用
- 手把手教您国外如何充值支付宝/微信教程
- 阿里云服务器突发性能型和共享型哪个好
- Java三目运算符 (Ternary Operator ? :)
- 读源码学算法之Monte Carlo Tree Search
- 【Android】debug 状态下其签名文件 debug.keystore 相关(如何获得该文件,其密码,获取其sha1、MD5等)
- 09、IO流—File类与IO流
- webstorm 激活破解方法
- 1-Adversarial Learning for Semi-Supervised Semantic Segmentation
- 2016 最新开发者账号 · 邓白氏申请申请流
- julia系列1:介绍与安装
- Python基于YOLOv7的火灾检测系统(源码&教程)
热门文章
- ArcGIS基础:相同空间人口图层的人口数量字段转移至小区图层(核心:相交操作)及制作人口密度专题图
- 矢量图、位图、RGB、YUV、JPEG、PNG的理解
- sql语句--黄一家
- 网易云音乐搜索引擎 python+whoosh---(3)界面
- win10桌面能不能写待办事件清单?
- 中国大学生服务外包【A类】参赛感想与经验(东部赛区)
- Mysql项目 github_GitHub 项目推荐|中国5级行政区域mysql库|基础数据|字典数据...
- python的扩展控制鼠标
- 国开计算机应用技术形考任务4答案,国开计算机应用基础形考任务答案.pdf
- 使用插件Bootstrap Fileinput文件上传