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 接入的三种常见方式

  1. 定时拉取:每隔几分钟或几小时,系统主动去调 API,把数据存到本地库
  2. Webhook 推送:源系统有数据变化时,主动推给你。实时性最好
  3. 实时查询:每次用户看报表时,直接调 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。核心逻辑就三步:

  1. 读取文件:判断文件后缀,选择对应的解析器
  2. 校验数据:检查必填字段、数据类型、格式
  3. 写入临时表:先存到 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 多线程处理。但要注意,数据库写入要加锁或使用批量插入,不然容易死锁。

好了,数据源接入这块就聊到这儿。三种方式各有适用场景,你根据实际情况选就行。下一章咱们聊聊数据清洗和转换,那才是真正考验功力的地方。