核心是分阶段解耦、流式解析与合理批控:用jackson streaming api逐对象解析,内存查重预判insert/update,500–1000条分批提交,禁用fastjson,调优jvm及mysql参数。

处理海量 JSON 数据并批量落库,核心在于“分阶段解耦 + 合理批控 + 资源适配”。不是一次性全量解析再插入,而是边解析、边转换、边分批提交,避免内存溢出和数据库阻塞。
JSON 解析要轻量、流式、按需
面对上万甚至百万级 JSON 数据(比如主数据同步接口返回的数组),别用 JsonNode 或 JSONObject 一次性加载整个字符串——这极易触发 OOM。推荐 Jackson 的 Streaming API(JsonParser):
- 逐个读取 JSON 数组中的对象,不缓存全部结构
- 遇到
START_OBJECT就开始解析一个实体;遇到END_OBJECT就立即转成 Java 对象(如User)或 Map - 配合
@JsonCreator和@JsonProperty控制字段映射,跳过无关字段,减少反序列化开销
入库前先做去重与分类判断
直接遍历每条数据查库再决定 insert/update,是性能杀手。更高效的做法是:
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
- 提前查出目标表中所有主键(如
id)到内存 Set 中(HashSet<long></long>),利用 O(1) 查找优势 - 解析出一条记录后,立刻检查其 id 是否在该 Set 中:存在 → 加入 update 列表;不存在 → 加入 insert 列表
- 同步把已命中的 id 从 Set 中移除,最后剩余的 id 就是待删除项(如需软删或清理)
批量执行要分片、设阈值、关自动提交
MyBatis 或 JDBC 批量写入不能无脑传一万条——MySQL 默认 max_allowed_packet 通常只有 4MB,单次 SQL 过长会报错;JVM 也扛不住超大 List。建议:
- 每 500~1000 条为一个批次(根据单条数据大小动态调整)
- 使用 MyBatis 的
<foreach></foreach>拼接多值 INSERT(注意 MySQL 的rewriteBatchedStatements=true参数必须开启) - 或用 JDBC
addBatch()+executeBatch(),手动控制事务:开始前connection.setAutoCommit(false),成功后commit(),失败则rollback()
关键配置与避坑点
几个容易忽略但影响巨大的细节:
- JVM 堆内存:解析+缓存中间数据需足够空间,-Xmx 建议设为 4G~8G(视数据规模)
-
MySQL 参数:除了
max_allowed_packet(建议设为 512M 或 1G),还要调大innodb_buffer_pool_size和bulk_insert_buffer_size -
Jackson 配置:禁用未知字段报错(
FAIL_ON_UNKNOWN_PROPERTIES = false),注册JavaTimeModule支持 LocalDateTime - 避免 Fastjson 1.x:已知多个高危反序列化漏洞,生产环境务必换 Jackson 或 Gson 2.10+
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










