2、数据源接入:关系型数据库(MySQL/SQL Server)连接、API数据源配置、Excel/CSV文件导入
做报表系统,第一步就是搞定数据源。说白了,你得先让系统能「吃到」数据,才能谈怎么展示。
我个人习惯把数据源分成三类:数据库、API、文件。这三类几乎覆盖了企业里 95% 的场景。今天咱们就挨个聊透。
2.1 关系型数据库连接(MySQL / SQL Server)
这是最传统、也是最常用的方式。OA 系统的数据,大部分都存在关系型数据库里。
连接配置的核心参数
不管用哪种数据库,你都得配好这几样东西:
- 驱动类名:MySQL 用
com.mysql.cj.jdbc.Driver,SQL Server 用com.microsoft.sqlserver.jdbc.SQLServerDriver - 连接地址:格式要写对,端口别漏
- 用户名 / 密码:建议单独建一个只读账号,别用 root
- 连接池参数:最大连接数、超时时间,这些直接影响并发性能
举个例子,MySQL 的 JDBC 连接串长这样:
jdbc:mysql://192.168.1.100:3306/oa_db?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8
SQL Server 的稍微有点区别:
jdbc:sqlserver://192.168.1.101:1433;databaseName=oa_db;encrypt=false
⚠️ 注意: 我曾经遇到过一个问题——时区没配,导致报表里的时间全部差了 8 小时。排查了半天,最后发现是连接串里少了
serverTimezone。嗯,这种坑踩一次就记住了。
连接池怎么配?
我个人习惯用 HikariCP,性能好,配置也简单。核心参数就这几个:
| 参数名 | 推荐值 | 说明 |
|---|---|---|
| maximumPoolSize | 10 ~ 20 | 最大连接数,别太大,数据库扛不住 |
| minimumIdle | 5 | 最小空闲连接,保证响应速度 |
| connectionTimeout | 30000 | 30 秒连不上就报错,别死等 |
| idleTimeout | 600000 | 10 分钟空闲就回收 |
💡 小技巧: 连接池的
maximumPoolSize 不是越大越好。你想想看,如果设成 100,数据库的 CPU 和内存瞬间就飙上去了。我一般按「并发数 × 2」来估算,然后压测调优。
2.2 API 数据源配置
现在很多新系统都走微服务架构,数据通过 API 暴露出来。比如钉钉的考勤数据、企业微信的审批流,都是通过 API 拿的。
API 接入的三种常见方式
- 定时拉取:每隔几分钟或几小时,系统主动去调 API,把数据存到本地库
- Webhook 推送:源系统有数据变化时,主动推给你。实时性最好
- 实时查询:每次用户看报表时,直接调 API 拿数据。适合数据量小的场景
我建议大部分场景用「定时拉取」。为什么呢?因为 Webhook 容易丢消息,实时查询又太慢。折中一下,定时拉取最稳。
API 配置的核心字段
一个标准的 API 数据源配置,通常包含这些:
- 请求地址:完整的 URL,包括协议、域名、路径
- 请求方式:GET 还是 POST
- 请求头:比如
Authorization: Bearer xxx - 请求参数:Query 参数或 Body 参数
- 数据路径:从返回的 JSON 里提取数据的字段路径,比如
$.data.list - 分页方式:页码分页还是游标分页
举个例子,一个典型的 API 配置 JSON 长这样:
{
"url": "https://api.example.com/v1/attendance",
"method": "POST",
"headers": {
"Authorization": "Bearer eyJhbGciOiJIUzI1NiIs..."
},
"body": {
"startDate": "2024-01-01",
"endDate": "2024-01-31",
"page": 1,
"pageSize": 100
},
"dataPath": "$.data.records",
"pagination": {
"type": "page",
"pageField": "page",
"totalField": "$.data.total"
}
}
🔑 关键点: API 返回的数据结构一定要先看清楚。我见过有人配错了
dataPath,结果拿到的是一整个对象,不是数组,报表直接报错。建议先用 Postman 调通了再配。
2.3 Excel / CSV 文件导入
别小看文件导入。很多业务部门就喜欢用 Excel 整理数据,然后丢给你说:「帮我把这个导进系统。」
文件导入的常见痛点
- 格式不统一:有的用 .xlsx,有的用 .xls,还有用 .csv 的
- 编码问题:CSV 文件经常出现乱码,尤其是中文
- 数据类型混乱:日期字段有的写「2024-01-01」,有的写「2024/1/1」
- 空行和合并单元格:Excel 里经常有合并单元格,解析起来很头疼
我的处理方案
我一般用 Apache POI 处理 Excel,用 OpenCSV 处理 CSV。核心逻辑就三步:
- 读取文件:判断文件后缀,选择对应的解析器
- 校验数据:检查必填字段、数据类型、格式
- 写入临时表:先存到 staging 表,等用户确认后再正式入库
代码示例(Java 伪代码):
// 判断文件类型
if (fileName.endsWith(".xlsx") || fileName.endsWith(".xls")) {
workbook = new XSSFWorkbook(inputStream);
sheet = workbook.getSheetAt(0);
} else if (fileName.endsWith(".csv")) {
reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
// 逐行读取
}
// 校验每一行数据
for (Row row : sheet) {
String dateStr = getCellValue(row.getCell(0));
// 尝试解析多种日期格式
if (!isValidDate(dateStr)) {
throw new DataException("第 " + rowNum + " 行日期格式错误");
}
}
⚠️ 避坑指南: 我曾经遇到过一个 CSV 文件,用 Excel 打开显示正常,但程序读出来全是乱码。后来发现是文件用了 GBK 编码,而程序默认用了 UTF-8。从那以后,我每次读 CSV 都会先检测 BOM 头,或者让用户指定编码。
文件导入的最佳实践
- 模板先行:给用户提供一个标准模板,里面写好示例数据和格式说明
- 分批处理:如果文件有 10 万行,别一次性全读到内存里,会 OOM 的。我一般每 1000 行提交一次
- 错误反馈:哪几行有问题,具体是什么错误,要清晰地告诉用户。别只给个「导入失败」
💡 小技巧: 对于超大 CSV 文件(比如超过 100MB),我建议用
BufferedReader 逐行读取,配合 ExecutorService 多线程处理。但要注意,数据库写入要加锁或使用批量插入,不然容易死锁。
好了,数据源接入这块就聊到这儿。三种方式各有适用场景,你根据实际情况选就行。下一章咱们聊聊数据清洗和转换,那才是真正考验功力的地方。