ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Spring Boot+MySQL信息管理系统开发全流程:从数据库设计到部署避坑

Spring Boot+MySQL信息管理系统开发全流程:从数据库设计到部署避坑 做Java课程设计或者毕业设计Spring Boot 加 MySQL 这套组合基本是绕不开的。之前不少学弟学妹问我一个信息管理系统到底要准备哪些东西数据库要建几张表、代码目录怎么分、部署的时候为什么老是报错今天我把这套新冠检测信息管理系统的完整拆解写出来。项目本身是典型的“业务增删改查统计报表”结构但正因为典型反而适合一条线讲清楚从需求分析、数据库设计、核心代码实现、调试部署到论文撰写全流程。不管你手里拿的是不是同款项目只要把这篇的思路吃透换一个业务场景照样能套。我尽量不说废话直接按实际开发时的顺序来。文章里涉及的表结构、代码写法、部署步骤都是可以直接抄作业的数据库脚本和源码的组织方式我也会讲明白最后会集中说一说那些文档里一般不写、但实操时一定会踩的坑。1. 项目概述与需求拆解1.1 系统定位与核心业务这个系统本质上是一个面向检测机构或社区管理场景的信息化工具管理的是“检测对象登记、检测过程记录、结果录入与查询、数据统计分析”这一整条链路。用大白话说就是把原本用Excel登记、纸质流转的流程搬到网页上让工作人员可以录入人员信息、登记检测批次、回填检测结果让管理员能看到按日期、按区域、按结果类型统计的报表同时给不同角色分配不同的操作权限。做这类系统最忌讳一上来就写代码。我见过太多同学打开IDEA直接建Controller结果做到一半发现缺字段、缺表、角色权限混乱。正确顺序应该是先捋清楚角色和用例。这套系统里至少要拆出三种角色系统管理员、检测录入人员、查询浏览人员。管理员管账号和基础数据录入人员管人员登记和结果回填浏览人员只做查询和报表查看。角色拆清楚了菜单和接口的边界自然就清楚了。1.2 功能模块划分按业务流程拆整个系统可以切成六个模块登录认证模块负责拦截未登录请求和权限校验人员信息管理模块负责检测对象基本信息的增删改查包括姓名、证件号、手机号、住址、所属区域这些字段检测记录管理模块负责生成检测批次、关联检测人员和样本编号结果管理模块负责回填检测结果支持“阴性、阳性、待复核”几种状态统计报表模块按日期、区域、结果类型做聚合统计用图表展示系统管理模块负责用户、角色、菜单和公告的维护。每个模块拆出来以后再去看里面的核心字段。比如人员信息肯定要有唯一标识、身份证号、联系方式检测记录要有检测日期、检测类型混检还是单检、样本编号、对应的检测机构结果表要有结果状态、检测时间、操作人。把这些字段提前列成清单后面建表和写实体类就是体力活了。1.3 项目交付物里都有什么标题里说“程序源码数据库调试部署开发环境论文文档”这其实就是一个完整课设/毕设项目的标准交付清单。源码是Maven工程包含后端Java代码、前端页面、配置文件数据库是一份SQL脚本建库建表加初始数据一次性执行开发环境文档会写清楚JDK版本、IDE配置、Maven仓库怎么设部署文档则是从打包到运行的完整步骤。论文文档一般是一万字左右后面我会专门讲这部分怎么组织和扩充。这套东西在课程设计、毕业设计里非常常见我下面讲的每一块都会对应到交付物里的具体文件。2. 技术选型与架构设计2.1 为什么是Spring Boot而不是SSM很多教材还在教SSMSpring Spring MVC MyBatis但实际做项目、找工作面试时Spring Boot已经是绝对主流。Spring Boot最大的价值是“约定优于配置”内嵌Tomcat不需要打WAR包丢到外部容器里一个java -jar就能跑。它把SSM里大量XML配置变成了自动配置和注解开发效率高很多。我给学生讲的时候常说SSM是手动挡Spring Boot是自动挡都能开到目的地但自动挡省心得多。选Spring Boot还有一层考虑这个项目是课程设计/毕业设计答辩时老师一定会问“为什么选这个技术栈”。Spring Boot现在的生态、社区资料、招聘需求都是最旺盛的回答“方便快速开发、便于维护、符合企业主流技术栈”非常站得住脚。版本上建议直接用Spring Boot 2.7.x稳定资料多JDK 1.8完美兼容不要追求最新的Spring Boot 3.x因为3.x强制JDK 17很多学校的评测环境还停留在JDK 8。2.2 持久层框架选型持久层我用的是MyBatis-Plus这个选择可以多说两句。传统MyBatis写增删改查要自己写XML里的SQL单表操作特别烦。MyBatis-Plus在MyBatis之上提供了BaseMapper单表CRUD不用写一行SQL内置分页插件还有代码生成器可以直接生成实体类、Mapper、Service、Controller。对于这种信息管理系统大部分操作就是单表增删改查加联表查询MyBatis-Plus能把开发周期缩短三分之一。当然这不代表SQL不用学。联表查询、统计报表、复杂条件筛选仍然要手写SQLMyBatis-Plus的LambdaQueryWrapper只是帮你把简单重复的活干了真正的统计逻辑还是要自己组织。我在第4节会给出统计模块的具体SQL例子。2.3 前端方案与整体分层前端有两种常见做法一种是Thymeleaf服务端渲染模板直接放在resources/templates下写起来简单适合一个人完成的小项目一种是前后端分离Vue加Element UI请求接口拿JSON数据渲染。我建议课程设计选Thymeleaf加Bootstrap或者Layui理由很现实前后端分离意味着你要额外维护前端工程、处理跨域、做接口联调工作量直接翻倍。而Thymeleaf是Spring Boot原生支持的模板引擎后端返回ModelAndView就能渲染页面页面里用Bootstrap把表格和表单一美化视觉效果完全不差。后端分层是经典的四层结构Controller接收请求和参数校验Service写业务逻辑和事务控制Mapper负责数据库操作实体类对应表结构。Exception统一处理用RestControllerAdvice全局返回统一格式的Result对象这样前端拿数据、后端报错都有固定格式可依赖。3. 数据库设计与数据模型3.1 表结构规划数据库是整个系统的地基地基歪了后面全白搭。这套系统的核心表我建议按下面这个列表来设计一共七张表。用户表sys_user字段有id、username、passwordMD5加密存储、real_name、role_id、create_time、status。角色表sys_role存角色编码和角色名称用字典值区分admin、operator、viewer。人员信息表person_info字段包括id、person_name、id_card身份证号、phone、address、region_code区域编码、gender、age、create_time身份证号和手机号要建索引因为这两个是高频查询条件。检测记录表test_record字段有id、record_no流水号、person_id关联人员表、test_date、test_type单检/混检、sample_no样本编号、institution、operator_id操作人。结果表test_result字段有id、record_id关联检测记录、result_status阴性/阳性/待复核、test_time、operator_id、remark。最后加一张公告表notice和一张操作日志表sys_log日志表用于记录关键操作的痕迹答辩的时候提到审计功能是加分项。3.2 字段设计的几个细节字段类型和长度要在建表时就定好不然后期改表会牵连实体类和页面。身份证号用varchar(18)手机号varchar(11)这是固定长度用char也可以但varchar更节省空间。状态字段用tinyint或者varchar存字典值我习惯用varchar存编码比如result_status存字符串“negative”“positive”“pending”比数字可读性强写代码的时候不会搞混。时间字段统一用datetime注意MySQL 8.0之前datetime默认不带毫秒不影响这个业务。所有业务表都建议加create_time和update_time两个字段MyBatis-Plus有自动填充注解TableField(fill FieldFill.INSERT)配合MetaObjectHandler可以免去手动维护时间。逻辑删除字段deleted也建议加上用TableLogic注解这是MyBatis-Plus内置的支持删数据变成更新标记避免误删和保留历史。3.3 主外键与索引设计主键直接用自增id业务上对外展示时可以用record_no这样的流水号不要把业务编号当主键。外键我建议在逻辑层面维护而不是在数据库层面强加FOREIGN KEY约束。原因很简单逻辑外键在代码里通过JOIN关联性能和灵活性更好物理外键在删除父表数据时容易触发约束错误课设项目里被这种问题卡住不值得。但是索引一定要建person_id在test_record表里建普通索引test_date在test_record和test_result里建普通索引统计模块天天按日期和人员维度查询没有索引数据量稍微一上去就非常慢。统计报表的SQL可以提前想好比如“按日期统计检测数量”就是SELECT test_date, COUNT() FROM test_record GROUP BY test_date ORDER BY test_date DESC“按结果类型统计”就是SELECT result_status, COUNT() FROM test_result GROUP BY result_status。这些语句写进Service层用Mapper的Select注解直接挂SQL比用QueryWrapper硬拼要清爽得多。4. 核心功能模块的实现4.1 登录认证与权限拦截登录这块我用的方案是Session加拦截器不用JWT理由是这个系统是单体应用不需要跨域和分布式Session支持Session天然简单可靠。用户登录成功后把用户信息和角色放进session然后写一个HandlerInterceptor在preHandle方法里判断session里有没有用户没有就重定向到登录页有就放行。权限控制再细一层用注解或拦截路径控制Controller的访问比如“/admin/**”开头只允许管理员角色访问在拦截器里检查session里的角色编码。密码存的是MD5加盐的哈希值MD5虽然现在不算强加密但课设项目足够也容易解释。加盐就是“用户密码固定盐值”再做MD5防止两个用户同密码得到相同哈希值。有些同学会问要不要用BCrypt当然更好但MD5加盐配合Spring自带的DigestUtils工具类已经能让答辩老师满意。4.2 人员信息与检测记录CRUD人员管理和检测记录管理本质就是增删改查加分页。有了MyBatis-Plus之后分页用内置的PaginationInnerInterceptorController接收current和size两个参数Service里Page page new Page(current, size)然后mapper.selectPage(page, wrapper)返回的IPage里就有总记录数、总页数、当前页数据这些标准结构前端表格直接翻页就行。这里有一个注意点查询条件不要全写在一个方法里。我的做法是PersonQuery对象封装personName、idCard、phone、regionCode这些可选条件在Service里用LambdaQueryWrapper动态拼接。条件判断用StringUtils.hasText(personQuery.getPersonName())这样没有值就不加条件有值才拼进去页面搜索用户体验会好很多。联表查询的场景集中在检测记录列表列表页要显示检测人员姓名、身份证号这些字段在person_info表里而test_record表只存person_id。两种处理方式一种是写自定义SQL做JOIN一种是查询后根据person_id批量查人员表再组装。数据量小的时候两种都行我更推荐写SQL因为代码直观、一看就懂也为统计模块打基础。4.3 结果录入与统计报表结果录入是整个系统里业务逻辑最特殊的一块。录入人员选择一条检测记录回填检测结果系统自动记录操作人和操作时间还要校验结果状态值必须是“阴性、阳性、待复核”三者之一不能手输随便填。这里我用枚举类ResultStatusEnum管理状态码和描述前端下拉框渲染枚举value后端Controller入参用Validated校验非法值直接返回参数错误。统计报表是答辩时最容易出彩的部分。我用ECharts做前端图表后端提供聚合数据接口。接口返回的数据结构是List每个元素是{date: “2024-01-15”, total: 320, negative: 310, positive: 5}这样的对象。SQL写法是从test_record JOIN test_result按日期分组统计总数和各状态数量。ECharts里用柱状图展示每日检测量饼图展示结果类型占比折线图展示近两周趋势视觉表现力比表格强很多答辩时往大屏上一放老师一眼就能看到工作量。4.4 数据导出与公告管理Excel导出这种功能属于加分项实现方式比想象中简单。我用EasyExcel引入依赖后定义好实体类字段和ExcelProperty注解导出时一行代码写进输出流前端用window.location或a标签触发下载接口。导出内容一般是按当前筛选条件查询全部数据注意不用分页直接查全量后写入Excel。这块功能量不大但在答辩时能展示你的工程化意识建议加上。公告管理就是一张表加一个富文本编辑器的路子。富文本我用的是wangEditorBootstrap风格的界面集成起来很简单。公告在首页轮播或者列表展示后台可以发布、编辑、下线公告权限限定为管理员。别小看这个模块它让系统看起来像完整的产品而不是半成品。5. 调试部署与开发环境搭建5.1 开发环境准备开发环境这块我建议按这个组合装JDK 1.8版本号1.8.0_202以上、Maven 3.6.x、MySQL 5.7或8.0、IDEA 2022版以上、Navicat或者DBeaver作为数据库客户端。第一次跑项目最容易出问题的有三个点。第一个是Maven仓库下载依赖太慢配置阿里云镜像就能解决。在Maven的settings.xml里加一个mirror节点url指向阿里云的maven-public仓库速度能快几十倍。第二个是IDEA里项目的SDK和Maven配置对不上确认Project Structure里的Project SDK选的是1.8Maven设置里Runner的JRE也选1.8不然编译报“invalid source release: 11”这类错误。第三个是MySQL的时区问题连接URL里要加serverTimezoneAsia/Shanghai和useUnicodetruecharacterEncodingutf8不然会报时区错误或者出现中文乱码这是绝大多数新手必定会遇到的坑。5.2 初始化数据库与导入源码拿到项目包后先执行数据库脚本再用IDEA导入源码。数据库脚本一般是sql文件里面包含CREATE DATABASE、CREATE TABLE和INSERT初始数据。在Navicat里新建数据库连接选择脚本文件直接运行就能建好库。注意脚本里如果有SET NAMES utf8mb4说明建表时用的字符集是utf8mb4这个字符集能存emoji和生僻字比utf8更完善页面上看到中文乱码时优先确认数据库字符集和连接串字符集是否一致。导入源码时用IDEA的Open选择项目根目录Maven项目会自动识别pom.xml并下载依赖。如果右下角提示“Maven projects need to be imported”选择Enable Auto-Import。第一次导入会花几分钟下载依赖这时候别急着点运行先等依赖下载完再看右侧Maven面板里有没有报红。如果某些依赖下载失败清理IDEA缓存File - Invalidate Caches再重新导入是最快的。5.3 打包与部署运行本地运行和部署到服务器是两个层面。本地运行时IDEA直接点SpringBootApplication主类的main方法即可等控制台出现“Started Application in x.xxx seconds”就是启动成功然后浏览器访问localhost:8080。部署到服务器时先在pom.xml确认打包方式是jar然后执行mvn clean packagetarget目录下会生成一个可执行的jar包。把这个jar包上传到服务器运行nohup java -jar xxx.jar run.log 21 即可后台启动。第一次运行建议不要加nohup直接前台运行把控制台日志完整看一遍确认没有报错再加后台运行参数。端口默认8080如果要改成8081用java -jar xxx.jar --server.port8081或者在application.yml里配置。5.4 常见启动报错速查我把这些年带项目遇到的启动报错整理成一张速查表大家在部署阶段对照排查就行。报错现象根本原因解决方法Access denied for user ‘root’‘localhost’数据库密码配置错误核对application.yml里spring.datasource的username和passwordUnknown database ‘xxx’数据库脚本没执行或库名对不上在Navicat里确认数据库是否存在库名是否和配置一致Server returns invalid timezoneMySQL时区问题连接URL加serverTimezoneAsia/ShanghaiPort 8080 was already in use端口被占用用netstat -ano查看占用进程kill掉或改端口Failed to configure a DataSource没配置数据库连接信息检查application.yml里的datasource配置是否存在中文乱码字符集不统一连接URL加characterEncodingutf8页面文件用UTF-8编码6. 数据库脚本、源码结构与论文写作6.1 数据库脚本的规范写法好的数据库脚本不只是CREATE TABLE那么简单还要包含建库语句、USE语句、DROP TABLE IF EXISTS方便重复执行、建表语句、注释和初始数据。列注释写在每一列后面用COMMENT关键字表头也要有COMMENT这样反向生成数据库文档时一目了然。初始数据至少要有一个管理员账号admin/admin123这种一个录入人员账号一个查询人员账号人员信息表插入10到20条测试数据检测记录表按不同日期插入几十条数据检测结果表也要有不同状态的分布。没有初始数据系统登录进去页面全是空的展示效果大打折扣答辩也缺少数据支撑。我一般会把演示数据专门配一批比如近两周每天都有检测记录让统计图看起来有起伏变化。6.2 源码目录与包结构设计源码结构我这里给一个可以直接用的包组织方式按功能模块分包而不是按技术类型分包这样代码的归属更清晰。com.example.covid19 ├── controller # 控制层 │ ├── LoginController │ ├── PersonController │ ├── TestRecordController │ ├── TestResultController │ ├── StatsController │ └── SystemController ├── service # 业务层接口 │ └── impl # 业务实现类 ├── mapper # MyBatis-Plus的Mapper接口 ├── entity # 实体类 ├── dto # 请求参数对象和返回对象 ├── config # 配置类如拦截器、MyBatis-Plus分页插件 ├── common # 统一返回结果、异常处理、枚举类 └── utils # 工具类如MD5加密Controller只负责接收参数和返回结果业务逻辑一律写在Service里Mapper只做数据访问。这个习惯坚持下来写论文时画架构图很容易答辩被问到“为什么这样分层”也很好回答——职责单一、便于维护和扩展。6.3 一万字论文怎么组织论文文档是不少同学的痛点其实理清楚框架后并不难。一份标准的课设/毕设论文目录大致如下摘要和关键词绪论背景、意义、国内外现状、主要工作需求分析功能需求、非功能需求、用例图系统设计架构设计、功能模块设计、数据库设计含ER图和表结构系统实现每个核心模块的界面截图加核心代码讲解系统测试测试环境、功能测试用例、测试结论总结与展望参考文献。一万字听起来多分配到每个章节其实压力并不大。摘要写三四百字绪论写两三千需求分析加用例写两千系统设计和数据库设计写三千系统实现按模块每个写七八百字测试和总结各一千总字数自然就过万字了。注意论文里一定要有图用例图、架构图、ER图、流程图、每个功能模块的截图。有图就能撑起字数而且老师看论文第一眼就是看图密不密。论文里贴代码要挑核心的贴不要贴整段Controller或者Mapper而是贴登录拦截、分页查询、统计SQL这种有逻辑含量的片段每个片段后面跟一段文字解释“这段代码做了什么事、为什么这么写”。这种代码加解释的组合是论文质量的核心。6.4 界面设计与演示准备系统界面是答辩的第一印象界面做得整齐能帮你省掉很多解释工作。我用的是Bootstrap后台管理模板左侧菜单加右侧内容的经典布局。菜单项要和功能模块一一对应系统管理、人员信息、检测记录、结果管理、统计报表、公告管理登录进来看到什么一目了然。表格类的页面统一做条件搜索框、重置按钮、新增按钮、编辑和删除操作列底部做分页条。表单页统一用横向表单项布局带必填项校验提示。颜色不要花哨一套主色贯穿所有页面就够了。这些界面截图在论文里就是最好的“系统实拍”证据比文字描述有说服力得多。答辩前一定要自己完整走一遍演示流程登录、新增人员、给该人员新增检测记录、录入结果、查看统计图表、导出Excel、退出登录。每一步心里有数万一老师让你现场操作也不会慌。7. 实操中的坑与排查经验7.1 开发阶段最隐蔽的坑开发阶段有几个坑特别容易消耗时间我逐个说一下。第一个是MyBatis-Plus的逻辑删除和唯一索引冲突。如果人员信息表给身份证号建了唯一索引逻辑删除后再次添加同一身份证号的人会报Duplicate entry因为那条数据没被真正删除。解决办法是给身份证号字段再加一个逻辑删除标记的联合唯一索引或者去掉唯一索引只做普通索引并在Service层手动校验。第二个坑是前端表单提交日期格式问题。页面上的日期选择器默认传递yyyy-MM-dd格式而后端实体类的Date字段默认解析成yyyy-MM-dd HH:mm:ss表单提交时直接报格式错误。解决办法是在日期字段上加JsonFormat(pattern “yyyy-MM-dd”, timezone “GMT8”)注解或者Controller入参用String接再用工具转换。第三个坑是Thymeleaf页面引用静态资源路径一定要用th:href{/xxx.css}这种语法用普通href的话部署到服务器上路径容易错。7.2 统计报表数据的常见Bug统计模块的Bug往往不是代码报错而是数据不对。最常见的问题是统计数据翻倍原因是JOIN多张表之后产生笛卡尔积比如test_record关联test_result时如果一张record对应多条resultCOUNT就会重复统计。解决思路是先明确统计的目标表尽量在一张表上做GROUP BY需要关联时才JOIN而且要确定关联关系是“一对一”才安全。另一个问题是日期分组跨时区。如果MySQL服务器时区是UTC而业务上按中国时间统计每天的归属日期就会差8小时。解决方案是启动参数加-Duser.timezoneAsia/Shanghai同时数据库连接串指定serverTimezoneAsia/Shanghai。这个问题在部署到云服务器时尤其容易踩本地环境反而没事因为本地和数据库同一时区。7.3 排查问题的通用思路最后说一个通用的排错思路这也是我带学生时反复强调的。项目出了bug不要先在浏览器里乱点乱试按照“控制台日志 - 数据库状态 - 前端请求”的顺序排查。第一步看后端控制台有没有异常堆栈大部分问题都能在这里找到具体错误信息比如SQL语法错误、空指针、参数绑定失败。第二步确认数据库里的数据状态是否符合预期比如明明新增了记录却查不到就要看是不是事务没提交或者查错了表。第三步打开浏览器F12看Network面板查看请求URL、请求参数、响应状态码判断是前端没传参还是后端报错。按这个顺序走下来90%的问题五分钟内能定位。对于确实找不到头绪的问题我还有个习惯写一个最小的测试用例。比如怀疑某个查询SQL有问题就单独用Navicat跑一遍那条SQL看结果对不对。SQL没问题就怀疑MyBatis-Plus的映射映射没问题就怀疑参数组装。把问题缩小到一个具体的怀疑点比无头苍蝇一样到处打断点要高效得多。7.4 我最后想给的几条实在建议以前带过的学弟学妹里做得好的和做得差的差距往往不在编码能力而在做事的顺序和心态。第一个建议是不要直接从代码开始先花半天把数据库表建好、把页面原型画出来后面开发就是填肉的过程。第二个建议是每天提交一次代码到Git哪怕只是改了一个样式这个习惯关键时候能救命。第三个建议是给自己的每个模块留出足够的测试时间课设挂掉最多的原因不是功能没做完而是做完的功能一演示就崩。这套系统的难点不在某个单一技术而在于把所有模块串成一个完整的闭环再把它说清楚、写出文档、跑通部署。你把它拆开看每一块其实都是Spring Boot和MySQL最常规的用法。这也是我为什么愿意写这么长一篇的原因——真正吃过一遍完整的流程后面再做任何管理系统都是同一套思路的平移。如果你手里有类似的系统要做从数据库到部署把这篇里的步骤按顺序来一遍基本不会出大问题。
返回列表