☰
SpringBoot新能源科普网站开发全流程:从数据库设计到部署实践
2026/10/7 3:10:02 网站建设 项目流程

做这个Springboot新能源科普网站的那段时间,我最大的感受是:科普内容本身不难写,难的是把“能源科普”做成一个有真实操作感的网站。整套系统是典型的SpringBoot单体架构,集成了数据库、后台管理、前台展示和图表可视化,拿到手之后能直接看到源码、数据库脚本、调试部署、开发环境配置的全套链路。这篇文章就把我实际开发、调试、部署这套系统的过程完整复现一遍,包括数据库怎么设计、接口怎么写、开发环境怎么搭、部署踩了哪些坑,以及那份一万字的论文文档是怎么组织出来的。不管你是要做类似毕业设计,还是单纯想通过一个完整项目入门SpringBoot开发,这篇文章都能当一份参考手册来用。

1. 项目整体架构与需求拆解

1.1 这个网站到底解决了什么问题

表面看,新能源科普网站就是一个内容展示站:放几篇关于光伏、风电、储能、氢能的科普文章,配上一些能源统计数据。但如果只做到这一步,它根本称不上一个“系统”。我当时给自己定的目标至少有三个层次:第一是前台展示层,访客能顺畅浏览分类文章和新闻资讯;第二是数据可视化层,用图表把太阳能装机量、风电发电量这类数据变成直观的曲线和饼图;第三是后台管理层,管理员能登录后台,对文章、分类、轮播图进行增删改查。

这三个层次对应着SpringBoot项目里最典型的能力:模板渲染、接口对接、权限拦截。做完这套,相当于把SpringBoot最常见的应用场景全部走了一遍。前台我用了服务端渲染的方式,页面由Thymeleaf模板直接输出,好处是部署时只需要打一个jar包,不用单独维护前端工程。数据可视化部分引入ECharts,前端页面通过Ajax从后端接口取JSON数据,再交给图表渲染。

这里有一个很多新手会纠结的点:到底用不用前后端分离?我的经验是,如果项目定位是科普展示类网站,后台管理也不是特别复杂,用SpringBoot + Thymeleaf的经典方式反而更合适。理由很简单:部署简单、调试直观、写论文时容易把请求流程讲清楚。前后端分离要维护两套工程、处理跨域、还要单独部署前端静态文件,在学生项目里很容易把自己绕晕。这个项目最终选择的是单体架构,这不是“落后”,而是“合适”。

1.2 技术选型与版本确定的理由

具体技术栈我定得比较传统,但每个选择都有原因,版本号我也全部锁死,避免依赖版本漂移带来的诡异报错。

组件选型理由
开发框架SpringBoot 2.7.12稳定、资料多,兼容JDK8,不会出现新版本里javax改jakarta的问题
ORM框架MyBatis-Plus 3.5.3单表CRUD不用写SQL,分页查询方便,能省大量重复代码
数据库MySQL 5.7主流、易安装,写论文时好找参考资料
模板引擎Thymeleaf 3.0.12SpringBoot官方整合方案,语法和HTML接近
图表库ECharts 5开源、图表类型丰富,科普网站展示数据很合适
工具库Hutool 5.8验证码、日期处理、文件上传都比较顺手

选MyBatis-Plus而不是原生MyBatis,我是吃过亏的。早期用原生MyBatis写文章模块,光ArticleMapper的XML文件里就写了一堆重复的resultMap和基础CRUD语句,后来换成MyBatis-Plus,单表操作基本不用写SQL,只有多表统计这种场景才在Mapper里自己写SQL,开发效率提升非常明显。有同学担心MyBatis-Plus会不会“不够底层”、写论文不好讲。实际上论文里写“使用MyBatis-Plus提高单表操作开发效率”本身就是个很合理的论据。

提醒一点:SpringBoot版本别选太高。我试过SpringBoot 3.x,结果javax包全部改成jakarta,很多老教程里的代码直接跑不起来。如果只是做科普网站这种常规CRUD项目,2.7.x加JDK8是最省心的组合,也最不容易在答辩时被细节问题卡住。

2. 核心功能模块与界面设计

2.1 前台展示模块怎么设计

前台面向普通访客,目标是让用户能快速找到感兴趣的内容。首页我划分成几个区域:顶部导航栏、轮播图、分类快捷入口、最新文章列表、推荐阅读、能源数据图表模块。

轮播图是后台可维护的,管理员上传图片和链接,前台自动轮播;如果后台没有配置轮播数据,页面会自动隐藏这个区域,不会出现空的占位块。文章列表按分类筛选,用分页展示,每条数据包含封面图、标题、摘要、发布时间和浏览量。文章详情页则更完整:标题、作者、发布时间、正文字体、上一篇下一篇。这样设计信息层级清楚,用户从列表到详情不会迷失。

在写页面时,我特别注意移动端适配。科普类网站有很大一部分流量来自手机浏览器,所以布局框架用了Bootstrap的栅格系统,文章正文区域设置了最大宽度,避免在手机浏览器上出现文字溢出。这个细节虽然不在需求文档里,但做完之后整体观感好了很多,系统演示时用手机访问也比桌面端截图更有说服力。

2.2 后台管理模块有哪些功能

后台和管理端是给网站维护人员用的,入口独立,路径是/admin,必须登录才能访问。功能模块包括仪表盘、文章管理、分类管理、留言管理、能源数据管理。

仪表盘展示几个统计卡片:文章总数、分类数量、留言数量、浏览量总和,下面再放一个近30天文章发布趋势图。文章管理是核心,列表支持分页、按标题搜索、按分类筛选,操作按钮包括编辑、删除、置顶、发布和取消发布。注意这里用的是逻辑删除,不直接从数据库里删掉记录,避免误操作导致内容丢失。分类管理比较简单,就是新增、修改、禁用、排序。留言管理用于处理前台访客提交的意见,管理员可以回复,回复后前台对应留言会显示回复内容。能源数据管理则是维护图表数据的入口,按能源类型、指标名称、年份、数值逐条维护。

这套后台功能不大,但把典型的权限控制、文件上传、分页搜索、表单校验都覆盖了。答辩时被问到“系统有哪些模块”时,按前台和后台两条线梳理,逻辑非常清晰。

2.3 数据可视化模块的实现思路

数据可视化是区别于普通CMS的亮点。我在首页设计了一个“能源数据看板”,用ECharts渲染四类图表:太阳能装机量趋势折线图、风电发电量柱状图、各能源类型占比饼图、近年一次能源消费结构堆叠图。

实现上有两条路可以走:一条是后端在页面渲染时直接输出数据到模板变量,另一条是后端提供JSON接口,前端页面加载后通过Ajax异步取数。我选择的是后者。原因有两个:一是图表数据需要动态切换年份范围和能源类型,异步接口更灵活;二是接口本身可以作为独立功能写进论文里,体现前后端数据交互。

接口设计是GET /api/energy/trend?type=solar,返回给前端的JSON结构长这样:

{ "code": 200, "data": { "years": ["2018", "2019", "2020", "2021", "2022"], "values": [175, 204, 253, 306, 392] } }

前端拿到数据后,直接塞给ECharts的setOption方法。这里我踩了一个很典型的坑:ECharts的容器必须有明确的高度,如果CSS没有给图表容器设置height,图表数据请求完全正常,但页面上就是一片空白。后来给容器固定了height: 400px,图表立刻正常渲染。

3. 数据库设计与核心表结构

3.1 表结构怎么设计才不会返工

这个项目的表我做了一版优化。第一版很随意,文章表、分类表、用户表、留言表各建一张,字段也少,结果写到资讯管理时就发现缺字段,反复加列。第二版我干脆把所有核心字段一次性设计到位。最终主要表有这么几张:

  • 管理员表 admin_user:主键、用户名、密码(BCrypt加密)、昵称、角色、创建时间
  • 文章分类表 category:分类ID、分类名称、排序号、状态
  • 科普文章表 article:文章ID、分类ID、标题、封面图、摘要、正文、浏览量、是否置顶、是否发布、创建时间、更新时间
  • 留言反馈表 feedback:留言ID、用户昵称、联系方式、留言内容、回复内容、状态、创建时间
  • 能源数据表 energy_data:数据ID、能源类型(太阳能/风能/水能/核能等)、指标名称、数值、单位、统计年份

设计时有两个细节值得说。第一,每张表都带create_time和update_time,虽然是老生常谈,但后面做数据统计和按时间排序时真的省事。第二,文章表加了status字段,0表示草稿、1表示已发布,而不是“删掉就是不在前台显示”。这样后台编辑可以先存草稿,预览没问题再发布,逻辑上不会把“未完成”和“已发布”混为一谈。

3.2 建表SQL的关键写法与初始化数据

插入表结构时我统一使用utf8mb4字符集,而不是utf8。因为utf8在MySQL里最多只能存3个字节,科普文章中经常出现的生僻字、emoji或特殊符号可能会存不进去导致报错。下面这张分类表的SQL是典型写法:

CREATE TABLE `category` ( `id` INT NOT NULL AUTO_INCREMENT COMMENT '分类主键', `name` VARCHAR(50) NOT NULL COMMENT '分类名称', `sort` INT DEFAULT 0 COMMENT '排序号,值越小越靠前', `status` TINYINT DEFAULT 1 COMMENT '状态:1启用,0禁用', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='文章分类表';

表与表之间我设计的是逻辑外键而不是物理外键。article表里的category_id字段,我只是在Java代码里校验分类是否存在,没有在数据库层面加FOREIGN KEY约束。原因很现实:物理外键会拖累插入和删除性能,而且做数据初始化时必须按严格的依赖顺序插入,容易报错。这个项目属于教学演示性质,逻辑关联完全够用。

初始化数据我是用一个db_energy.sql脚本完成的,里面包含建库语句、所有建表语句,以及20多篇测试用科普文章和五年的能源统计数据。拿到全套源码后,只要执行一次脚本,就能得到一个可以直接登录、直接看到图表效果的数据环境。我建议做类似项目时也提供这样一份一键初始化脚本,这对后续部署和演示的帮助非常大。

4. 后端分层实现与核心接口讲解

4.1 Controller、Service、Mapper各自负责什么

我先把最核心的原则讲清楚:Controller里不要写业务逻辑,业务逻辑放在Service层。很多同学为了省事,直接在Controller里new一个Mapper查数据,数据量少的时候没问题,一旦需要校验权限、组合数据、处理事务,Controller就会变得又长又乱,而且不方便测试。

以文章列表为例。Controller只接收页面参数,然后调用Service层方法:

@Controller @RequestMapping("/article") public class ArticleController { @Autowired private ArticleService articleService; @GetMapping("/list") public String list(@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer size, Model model) { Page<Article> pageResult = articleService.pagePublishedArticles(page, size); model.addAttribute("pageResult", pageResult); return "article/list"; } }

Service层里封装真正的查询条件:只看已发布文章、按创建时间倒序、填充分类名称。这样Controller保持简洁,以后要加搜索、排序,只需要在Service层扩展,不用改动Controller。

我还在common包里放了统一返回结果类Result,接口统一返回code、message、data这样的结构。这样做的好处是前端判断逻辑非常统一,遇到异常也不会出现结构不一致导致的解析问题。对写论文也有帮助,可以直接画一张“统一返回结构图”。

4.2 后台权限控制的实现

科普网站的前台是公开的,谁都能看,但后台必须登录才能进。我用的方式是拦截器。在SpringBoot里注册一个Interceptor,拦截所有/admin/**路径,然后判断Session里有没有管理员登录标记。

public class AdminInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Object adminId = request.getSession().getAttribute("adminId"); if (adminId == null) { response.sendRedirect("/admin/login"); return false; } return true; } }

这段代码是最简单直观的登录控制方案,写论文时也好解释。如果你非要引入Shiro或Spring Security,项目复杂度会立刻提升一个台阶,但科普网站根本没有复杂角色权限需求,引入框架反而属于过度设计。记住一个原则:功能复杂度匹配需求复杂度,才是好的设计。

登录密码我用了BCrypt加密存储,不是明文。这样即使数据库文件泄露,也不会直接暴露管理员密码。注册逻辑这里没有做,后台管理员是初始化脚本里预设好的,这在毕业设计场景里完全够用。

4.3 能源数据图表接口的完整实现

回到数据可视化模块,接口实现其实不复杂,但涉及一个多表或分组查询。energy_data表里存的是按年份、能源类型、指标名称划分的数值,比如“太阳能-装机容量-2022-392”,要生成折线图就要把这个数据转换成前端需要的两个数组。

Service层大致做了三步:接收type参数、设置查询条件、按年份升序排序,然后组装成Map返回。

public Map<String, Object> getTrendData(String type) { LambdaQueryWrapper<EnergyData> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(EnergyData::getEnergyType, type) .orderByAsc(EnergyData::getStatYear); List<EnergyData> list = energyDataMapper.selectList(wrapper); List<String> years = list.stream().map(EnergyData::getStatYear).toList(); List<BigDecimal> values = list.stream().map(EnergyData::getValue).toList(); Map<String, Object> result = new HashMap<>(); result.put("years", years); result.put("values", values); return result; }

注意这里的LambdaQueryWrapper是MyBatis-Plus提供的构造查询条件的方式,不需要手写SQL,代码可读性也好。如果要写进论文,我会把列表查询、数据组装、前端ECharts渲染分成三步讲解,逻辑非常顺畅。

5. 开发环境搭建与调试部署完整流程

5.1 JDK、Maven、MySQL版本搭配

拿到源码第一步是把环境跑起来。我推荐的搭配如下:

工具版本说明
JDK1.8选择64位版本,配置JAVA_HOME环境变量
Maven3.6.3配置本地仓库和阿里云镜像
MySQL5.7安装后设置utf8mb4字符集
IDEIntelliJ IDEA2022及以上版本即可

JDK安装之后必须检查命令行里java -version是否正常。Maven下载后需要配置settings.xml,重点是本地仓库路径和阿里云镜像,不然从中央仓库拉依赖的速度会让人怀疑人生。我的镜像配置如下:

<mirror> <id>aliyunmaven</id> <url>https://maven.aliyun.com/repository/public</url> <mirrorOf>central</mirrorOf> </mirror>

配置完这个,依赖下载基本是秒级速度。另一个小技巧是在pom.xml里把所有依赖版本写清楚,优先使用SpringBoot父工程统一管理版本,避免某个子依赖版本不一致导致的运行期报错。

5.2 数据库初始化和项目配置文件

数据库初始化我用db_energy.sql。图形化方式用Navicat或DataGrip直接执行,命令行方式也很简单:

mysql -uroot -p source /path/to/db_energy.sql;

执行完成后,检查一下看到energy_db库,再看文章表里有没有20多条测试数据,有就说明导入成功。这一步如果看到中文乱码,大概率是连接字符集设置不对,可以在MySQL客户端执行set names utf8mb4;再重新导入。

application.yml是项目最核心的配置文件,数据库连接部分长这样:

spring: datasource: url: jdbc:mysql://localhost:3306/energy_db?useUnicode=true&characterEncoding=utf8mb4&useSSL=false&serverTimezone=Asia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver

serverTimezone这个参数曾经坑过我一整晚。旧版本MySQL驱动不写时区也能跑,换成新版驱动后直接报Server returns invalid timezone,明确加上serverTimezone=Asia/Shanghai才解决。

5.3 从打包到部署:jar包方式最省心

开发模式下直接运行EnergyApplication主类。要部署到服务器,用Maven打包成jar包,而不是war包,因为SpringBoot内置Tomcat,不需要再单独安装。

mvn clean package -DskipTests java -jar target/energy-project-0.0.1-SNAPSHOT.jar

如果服务器端口和配置不一致,启动时用参数覆盖即可:

java -jar energy-project.jar --server.port=8080

这个参数覆盖的好处是不用重新打包,改端口、改数据库密码都能直接跟在启动命令后面。服务器后台运行可以用nohup:

nohup java -jar energy-project.jar --spring.profiles.active=prod > log.log 2>&1 &

用了nohup之后,关闭SSH终端服务也不会停。调试时直接看log.log里的输出,报错信息非常直观。

5.4 部署过程中遇到的典型问题速查

我把自己部署时遇到的问题整理成一个速查表,这些全部是实际踩坑记录:

现象原因解决办法
启动报端口被占用8080端口被其他程序占用用netstat -ano查看PID,或启动时换端口
页面中文乱码数据库连接URL没指定字符集,或页面没设置UTF-8URL改成characterEncoding=utf8mb4,页面meta设置UTF-8
上传图片后无法访问没有把外部目录映射为静态资源实现addResourceHandlers方法
依赖下载慢默认Maven中央仓库在国外配置阿里云镜像
图表空白ECharts容器没有明确高度给容器固定height值

图片上传的问题值得多说一句。SpringBoot默认不会把外部目录映射成静态资源,我把上传图片放在D:/energy-upload/,然后在配置类加了资源映射:

@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/upload/**") .addResourceHandler("file:D:/energy-upload/"); }

注意最后那个斜杠必须写对,写成file:D:/energy-upload不带末尾斜杠,在某些系统上会映射失败。看到404不要慌,先检查路径格式。

6. 论文文档写作与全流程复盘

6.1 一万字论文的结构怎么组织

我写论文文档时最开始毫无头绪,后来把整个项目分成六章,写作思路一下子顺了。论文目录大致是:绪论、相关技术介绍、需求分析、系统设计、系统实现、测试与总结。绪论写新能源科普的背景、选题意义、国内外研究现状、论文结构安排;相关技术介绍就写SpringBoot、MyBatis-Plus、MySQL、Thymeleaf、ECharts;需求分析写功能性需求、非功能性需求、用例分析;系统设计写总体架构、功能模块设计、数据库表结构;系统实现是重点,每个核心模块写实现思路加核心代码截图;测试与总结写测试用例、成果总结、不足与展望。

字数分配上,系统实现那章占比最高,数据库设计这章用表结构说明文字填充,需求分析多用用例图。整篇下来一万字是很自然的事情。论文里不要大段贴代码,重点写“为什么这样设计”和“功能效果如何”,评委更看重的是你的设计思路,而不是代码数量。

6.2 我踩过的坑和给你的建议

这里分享几个实际操作中的独家经验。

第一个,Thymeleaf静态资源路径。模板里写静态资源一定要用th:href="@{/css/style.css}"、th:src="@{/js/app.js}"这种带@{}的语法。直接写href="/css/style.css",页面静态打开时没问题,但一旦走Controller返回视图,路径可能出错,浏览器加载不出任何样式。

第二个,MyBatis-Plus分页插件必须配置,否则分页参数不生效。我一开始忘了加PaginationInnerInterceptor,分页查询返回的total始终是0,页面一直只显示第一页。这个拦截器在文档里有完整示例,花两分钟配置一下就能解决。

第三个,做科普网站最好提前准备一份真实可靠的数据来源。我后来把公开发布的能源统计年报整理成Excel,再导入数据库,比手工造数据真实很多。这个小举动让系统演示时的说服力完全不同,写论文时也能把数据来源写进参考文献。

如果你要把这个项目继续扩展,我建议从两个方向入手:一是增加用户注册、收藏、点赞功能,让网站从单向传播变成互动社区;二是把ECharts图表维度增多,比如增加地图分布图,展示各省新能源装机的空间分布。这两个方向都能让论文的“创新点”更明确,也让这个Springboot新能源科普网站从一套毕业设计作品,变得更有实际应用价值。

最后说个实际体会:这种全栈单体项目最忌讳“贪多”,把前台展示、后台管理、数据图表三条线分别跑通,再考虑锦上添花。先把基础链路从数据库到页面完整打通,后面做任何功能都会顺手很多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询