FEATURED · 精选文章

Spring Boot免费数据源接入实战:H2与JSON构建舆情分析数据链路

发布时间 / 2026/9/1 3:15:52
来源 / 创域科博编辑部
栏目 / 资讯中心
Spring Boot免费数据源接入实战:H2与JSON构建舆情分析数据链路 在数据处理类项目中免费数据源是最容易被低估的一环。很多开发者第一次接触 Spring Boot 时以为数据源只是数据库连接串配好 URL、用户名、密码就能开始写接口。实际上对于舆情分析监测系统这类需要不断采集外部数据的应用来说数据源既包括本地数据库也包括离线文件、公开接口和第三方数据包。课程2.4把“免费数据源介绍与代码演示”单独作为一个章节核心目的不是替项目省数据库授权费而是让学生真正理解数据从哪里来、以什么格式进来、稳定性如何、能不能反复演示这些因素会直接决定后续数据处理流程是否可复现、可调试、可交付。下面按一条比较实用的主线展开先理解数据源在系统里的位置再对比常见免费数据源的选型方式然后准备一个 Spring Boot MyBatis-Plus 环境用 H2 数据库和 JSON 文件两个免费数据源完成可运行的代码演示最后扩展到多数据源、动态数据源和 Sharding 数据源注册。学完以后你可以在自己的课程项目、毕业设计或小型工具里快速搭出一套数据入口可替换的接入链路。1. 先理解什么是数据源以及“免费”在技术选型中的含义1.1 数据源的通俗含义和技术定义在正式写代码之前先把“数据源”三个字讲清楚。通俗地说数据源就是你要处理的数据放在哪里。它可能是一个 MySQL 数据库、一个 H2 内存库、一个 CSV 文件、一个 JSON 文件也可能是一个远程接口。只要程序能从这个入口拿到结构化数据这个入口就可以被称为数据源。在 Java 技术栈里数据源还有一个更精确的对应物就是javax.sql.DataSource接口。这个接口是 JDBC 规范的一部分它把“获取连接”这件事抽象出来让上层代码不必每次自己用DriverManager创建连接。引入DataSource之后连接池、事务管理、监控统计都可以统一挂在这个接口下面。Spring Boot 中的spring.datasource配置最后就是在容器里创建出一个DataSource实例再交给 MyBatis、JdbcTemplate 等组件使用。容易混淆的地方是数据源不等于数据库本身也不等于 JDBC 驱动。数据库是存储引擎驱动是与数据库通信的客户端库而DataSource是应用层管理物理连接的统一入口。很多新手报错“找不到数据源”时往往以为是数据库没启动实际上可能只是配置没生效或者驱动没引入。后面排错章节会专门展开。1.2 免费数据源不等于零维护“免费数据源”里的免费通常指不向数据提供方支付授权费用。常见类型包括嵌入式数据库、公开API、开放数据包、CSV/JSON 文件等。但免费不意味着没有使用成本。嵌入式数据库虽然不需要单独安装服务但它有自己的存储格式和并发限制公开API虽然数据丰富但有调用频率限制免费额度可能随时变化CSV/JSON 文件最容易理解却需要你自己完成解析、清洗和格式校验。在课程2.4里不少学生以为“用免费数据源就是图省事”结果把外部公开接口直接当作唯一数据来源接口一限流整个演示就垮了。更稳妥的理解是免费数据源适合学习、原型验证和低成本演示生产环境使用前必须评估数据稳定性、容量、许可证和运维成本。免费只是降低了进入门槛并没有降低数据治理的要求。1.3 免费数据源在舆情分析监测系统中的位置以“舆情分析监测系统”为例一个简化版系统的数据链路大致是免费数据源 - 数据采集与解析 - 标准化入库 - 分析与统计 - 页面展示。数据源位于最前端。如果数据源是公开新闻接口采集模块就要处理分页、限流和字段变化如果数据源是本地 JSON 文件采集模块就退化成文件读取和解析如果数据源是 H2 数据库程序可以直接通过 SQL 完成查询。数据源的类型决定了后续代码的复杂程度。课程2.4的代码演示会尽量覆盖两种最常用的免费数据源嵌入式数据库和 JSON 文件让后面讲采集、清洗、分析时有稳定的数据入口。2. 免费数据源选型嵌入式、文件型、公开API型怎么选2.1 三类免费数据源对比选择免费数据源时不应该只问“哪个免费”而应该问“在什么场景下哪个更合适”。三类最常见的免费数据源分别适用不同阶段。数据源类型典型代表优点缺点最佳使用场景嵌入式数据库H2、SQLite无需单独安装、启动快、支持 SQL数据量有限、并发处理能力较弱、持久化方式需要关注课程演示、单元测试、本地缓存、单机原型文件数据源CSV、JSON、Excel肉眼可读、容易造数、便于版本管理不适合复杂查询、解析需要额外代码、数据量大时性能差数据准备、批量导入、离线分析、测试样本公开API数据源各类开放接口数据实时、内容丰富、无需本地维护限流、鉴权、稳定性不可控、免费额度可能变化实时采集、课程展示、第三方数据接入对于课程2.4的代码演示建议先以 H2 和 JSON 文件为主把主链路跑通后再尝试接入公开API。这样即使公开接口不可用示例代码仍然可以运行。2.2 嵌入式数据库H2 是课程演示的首选H2 是一个用 Java 写的嵌入式数据库非常适合与 Spring Boot 配合。它有两种常见运行模式内存模式数据只存储在应用进程内存中进程结束数据就没了文件模式数据写入本地磁盘文件可以跨进程保留。课程演示最常用的是内存模式。连接 URL 大致如下jdbc:h2:mem:demo;MODEMySQL;DATABASE_TO_LOWERTRUE;DB_CLOSE_DELAY-1这句 URL 里有几个参数需要理解jdbc:h2:mem:demo表示在内存中创建一个名为 demo 的数据库。MODEMySQL表示使用 MySQL 兼容模式这样建表语句和查询语法更接近生产环境。DATABASE_TO_LOWERTRUE让表名和字段名统一转成小写避免因为大小写问题导致查询失败。DB_CLOSE_DELAY-1表示即使最后一个连接关闭内存数据库也不立即销毁方便在测试工具里查看数据。如果项目要求数据重启后还在可以把 URL 改成文件模式例如jdbc:h2:file:./data/demo同时注意及时备份数据和清理日志。2.3 文件数据源CSV/JSON 更适合做初始输入文件型数据源最适合课程项目的第一个阶段。原因很直接文件可以提交到 Git 仓库老师或同学可以打开看无需安装任何数据库服务。JSON 在 Java 生态里有 Jackson、Gson 等成熟解析库写几十行代码就能把一个列表读进内存。一个简单 JSON 数据文件可能长这样[ { id: 1, title: 某地举办科技创新大会, source: 本地新闻, sentiment: positive, hotScore: 86, publishTime: 2025-04-10 08:30:00 }, { id: 2, title: 某市发布交通出行提示, source: 城市公告, sentiment: neutral, hotScore: 67, publishTime: 2025-04-10 09:15:00 } ]这里的字段是按舆情分析常见维度设计的标题、来源、情感倾向、热度值、发布时间。文件数据源的好处是字段可以自由扩展坏处是程序无法直接用 SQL 查询。所以课程项目的常见做法是先用 JSON 文件作为原始输入解析后写入数据库后续统计都基于数据库完成。这样既保留了文件的可读性也获得了 SQL 的查询能力。2.4 公开API数据源可以先演示但不要卡在鉴权上公开API数据源最大的价值是数据实时。比如做一个舆情分析监测系统如果能从公开新闻接口拿到最新列表实时性会大幅提高。但免费API通常会有限流策略、Token 有效期和返回字段变更风险。在实际教学中接入公开API的难点往往不在代码而在账号和鉴权。有些学生申请接口账号后会在配置 API Key 上消耗大量时间。更稳妥的做法是在代码里定义一个外部接口客户端把接口地址、密钥、超时时间都放到配置文件中先用一个假的本地 JSON 模拟返回验证主链路后再切换为真实接口。这样即使接口申请不顺利课程进度也不会被阻塞。这里有一个取舍需要记住免费公开API适合做“扩展演示”不适合做“唯一数据源”。因为接口一旦限流或调整免费策略项目演示和数据复现都会受影响。3. 环境准备Spring Boot MyBatis-Plus 接入免费数据源3.1 需要准备的环境和版本为了让代码演示可复现先统一基础环境。以下版本是课程中常见的组合实际项目请以自己本地的依赖为准不要盲目照搬。组件推荐版本或说明JDK8 或 11建议 11部分新依赖要求更高Maven3.6 以上Spring Boot2.7.x 或 3.x课程示例按 2.7.x 编写MyBatis-Plus3.5.xH22.x 内置依赖即可Lombok可选用于简化实体类如果使用 Spring Boot 3.x需要注意jakarta包名变化以及 MyBatis-Plus 需要使用对应版本。稳妥做法是先看官方 release 说明。3.2 项目结构说明课程演示项目建议保持最小结构前后端不混在一起。目录结构如下demo-datasource ├── pom.xml ├── src/main/java/com/example/demo │ ├── DemoApplication.java │ ├── controller/NewsController.java │ ├── entity/NewsItem.java │ ├── mapper/NewsItemMapper.java │ ├── service/NewsService.java │ └── component/JsonDataLoader.java └── src/main/resources ├── application.yml ├── schema.sql ├── data.sql └── data/sample-news.jsonschema.sql用来创建表data.sql用来插入初始化数据application.yml里配置数据源和 MyBatis-Plus。JsonDataLoader专门负责读取 JSON 文件作为另一路免费数据源演示。3.3 引入 Maven 依赖pom.xml中核心依赖如下dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version /dependency dependency groupIdcom.h2database/groupId artifactIdh2/artifactId scoperuntime/scope /dependency dependency groupIdcom.fasterxml.jackson.core/groupId artifactIdjackson-databind/artifactId /dependency dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency /dependenciesmybatis-plus-boot-starter会带入 MyBatis 和 MyBatis-Plus 相关组件使用它之后不需要再单独引入mybatis-spring-boot-starter避免版本冲突。H2 的scope是runtime说明编译阶段不需要直接引用运行时会加载。jackson-databind是 Spring Boot 自带的 JSON 处理库显式写出来是为了表明 JSON 文件解析使用它。3.4 配置 application.ymlapplication.yml要同时完成三件事配置 H2 数据源、告诉 MyBatis-Plus 去扫描 Mapper、配置 JSON 文件路径。server: port: 8080 spring: datasource: driver-class-name: org.h2.Driver url: jdbc:h2:mem:demo;MODEMySQL;DATABASE_TO_LOWERTRUE;DB_CLOSE_DELAY-1 username: sa password: sql: init: mode: always schema-locations: classpath:schema.sql >DROP TABLE IF EXISTS news_item; CREATE TABLE news_item ( id BIGINT PRIMARY KEY, title VARCHAR(255) NOT NULL, source VARCHAR(64), sentiment VARCHAR(16), hot_score INT, publish_time VARCHAR(32) );这里把publish_time设计成VARCHAR是为了减少课程演示里时间格式转换的干扰。生产环境建议使用DATETIME或TIMESTAMP课程阶段用字符串更直观。data.sql插入两行数据INSERT INTO news_item (id, title, source, sentiment, hot_score, publish_time) VALUES (1, 某地举办科技创新大会, 本地新闻, positive, 86, 2025-04-10 08:30:00), (2, 某市发布交通出行提示, 城市公告, neutral, 67, 2025-04-10 09:15:00);再放置一个 JSON 数据文件src/main/resources/data/sample-news.json内容与前面示例一致。这个文件将作为第二路免费数据源模拟从外部接入的原始数据。4.2 实体类和数据访问层实体类NewsItem与news_item表对应Data TableName(news_item) public class NewsItem { TableId(type IdType.AUTO) private Long id; private String title; private String source; private String sentiment; private Integer hotScore; private String publishTime; }TableName指定表名TableId指定主键。MyBatis-Plus 默认会把hotScore转成hot_score查询前提是开启了map-underscore-to-camel-case。Mapper 接口只需要继承BaseMapperMapper public interface NewsItemMapper extends BaseMapperNewsItem { }继承BaseMapper后selectList、insert、updateById这些基础方法都可用不需要手写 XML。课程演示用基础方法足够。4.3 Service 层读取免费数据源并做简单聚合NewsService负责把两种免费数据源合并到统一结果中。先从 H2 数据库查询再从 JSON 文件读取最后合并返回。Service public class NewsService { private final NewsItemMapper newsItemMapper; private final JsonDataLoader jsonDataLoader; public NewsService(NewsItemMapper newsItemMapper, JsonDataLoader jsonDataLoader) { this.newsItemMapper newsItemMapper; this.jsonDataLoader jsonDataLoader; } public ListNewsItem listAll() { ListNewsItem dbList newsItemMapper.selectList(null); ListNewsItem jsonList jsonDataLoader.loadFromClasspath( data/sample-news.json ); ListNewsItem result new ArrayList(dbList); result.addAll(jsonList); return result; } public int countFromDb() { return newsItemMapper.selectCount(null); } }这里没有做去重是为了清晰展示两个独立数据源如何汇合到一个接口。实际项目中通常会给数据加sourceType或dataSource字段合并时按 id 或业务键去重。JsonDataLoader是一个独立组件专门解析 JSON 文件Component public class JsonDataLoader { private final ObjectMapper objectMapper; public JsonDataLoader(ObjectMapper objectMapper) { this.objectMapper objectMapper; } public ListNewsItem loadFromClasspath(String path) { ClassPathResource resource new ClassPathResource(path); try (InputStream inputStream resource.getInputStream()) { return objectMapper.readValue(inputStream, new TypeReferenceListNewsItem() {}); } catch (IOException e) { throw new RuntimeException(读取JSON数据源失败: path, e); } } }使用ClassPathResource可以避免手写文件绝对路径这样打包成 jar 后仍然能读到 classpath 下的文件。JSON 中的字段名与实体属性名一致Jackson 可以直接反序列化。4.4 Controller 和启动验证Controller 提供两个接口一个返回合并后的数据一个返回数据库统计数量。RestController RequestMapping(/api/news) public class NewsController { private final NewsService newsService; public NewsController(NewsService newsService) { this.newsService newsService; } GetMapping(/all) public ListNewsItem all() { return newsService.listAll(); } GetMapping(/count) public MapString, Integer count() { MapString, Integer result new HashMap(); result.put(dbCount, newsService.countFromDb()); return result; } }启动DemoApplication后访问http://localhost:8080/api/news/all预期返回 4 条数据其中前 2 条来自 H2 数据库后 2 条来自 JSON 文件。访问/api/news/count时预期返回 2因为统计的是数据库表里的数据。在控制台可以看到 MyB
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻