You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Java从MySQL导出关联实体数据的技术问题求助

流式导出MySQL关联实体数据的解决方案需求

问题描述

使用Java的JDBCTemplate queryForStream()实现超大规模MySQL数据库流式导出,处理3GB数据仅占用约600MB内存,普通实体导出完全正常。但当实体存在一对一关联关系时(如country与capital),无法获取关联实体的数据:导出时仅能得到country表的字段值,关联的capital字段为空,因为该字段不存在于country表中。

限制条件

  • 无法使用mysqldump导出数据,必须在导出前对数据进行预处理

核心代码

数据库查询主逻辑

try (Stream<?> dataStream = template.queryForStream(new StreamingStatementCreator(sql), getEntityRowMapper(clazz, converter, context))) { 
    // 数据处理逻辑
}

StreamingStatementCreator.java

public class StreamingStatementCreator implements PreparedStatementCreator {
  private final String sql;

  public StreamingStatementCreator(String sql) {
    this.sql = sql;
  }

  @Override
  public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
    final PreparedStatement statement = connection.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
    statement.setFetchSize(Integer.MIN_VALUE);
    return statement;
  }
}

EntityRowMapper相关方法

private EntityRowMapper<?> getEntityRowMapper(Class<?> domainType, JdbcConverter converter, JdbcMappingContext context) {
    return new EntityRowMapper<>(getRequiredPersistentEntity(domainType, context), converter);
}

private <S> RelationalPersistentEntity<S> getRequiredPersistentEntity(Class<S> domainType, JdbcMappingContext context) {
    return (RelationalPersistentEntity<S>) context.getRequiredPersistentEntity(domainType);
}

数据库表结构

country表

CREATE TABLE `country` (
  `code` int(11) DEFAULT NULL,
  `updated_by` varchar(100) DEFAULT NULL,
  `created_by` varchar(100) DEFAULT NULL,
  `name` varchar(50) DEFAULT NULL,
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `updated_on` datetime(3) DEFAULT NULL,
  `created_on` datetime(3) DEFAULT NULL,
  `version` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1

字段详情:

+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| code       | int(11)      | YES  |     | NULL    |                |
| updated_by | varchar(100) | YES  |     | NULL    |                |
| created_by | varchar(100) | YES  |     | NULL    |                |
| name       | varchar(50)  | YES  |     | NULL    |                |
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| updated_on | datetime(3)  | YES  |     | NULL    |                |
| created_on | datetime(3)  | YES  |     | NULL    |                |
| version    | bigint(20)   | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

capital表

CREATE TABLE `capital` (
  `name` varchar(50) DEFAULT NULL,
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `population` int(11) DEFAULT NULL,
  `country_capital_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `sys_country_capital_id` (`country_capital_id`),
  CONSTRAINT `fk__capital__country_country_capital_id_id` FOREIGN KEY (`country_capital_id`) REFERENCES `country` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1

字段详情:

+--------------------+-------------+------+-----+---------+----------------+
| Field              | Type        | Null | Key | Default | Extra          |
+--------------------+-------------+------+-----+---------+----------------+
| name               | varchar(50) | YES  |     | NULL    |                |
| id                 | int(11)     | NO   | PRI | NULL    | auto_increment |
| population         | int(11)     | YES  |     | NULL    |                |
| country_capital_id | int(11)     | YES  | UNI | NULL    |                |
+--------------------+-------------+------+-----+---------+----------------+

country表与capital表为一对一关联。

期望输出

导出的CSV文件需包含关联实体数据,示例如下:

|id  |code  |name   |capital                                            |createdBy   |createdOn     |updatedBy  |updatedOn      |version
|1   |91    |India  |{"id":1,"name":"New Delhi","population":1173902}   |System      |1.69E+09      |System     |1.69E+09       |0
|2   |91    |India  |{"id":2,"name":"New Delhi","population":1173902}   |System      |1.69E+09      |System     |1.69E+09       |0
|3   |91    |India  |{"id":3,"name":"New Delhi","population":1173902}   |System      |1.69E+09      |System     |1.69E+09       |0
|4   |91    |India  |{"id":4,"name":"New Delhi","population":1173902}   |System      |1.69E+09      |System     |1.69E+09       |0

需求

寻求可行的解决方案,实现流式导出的同时正确获取关联实体的数据。

内容的提问来源于stack exchange,提问作者Emperor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 04:43:08