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

如何在Java中逐行将S3中的CSV文件写入DynamoDB

实现S3 CSV文件到DynamoDB StatusObject的转换(忽略多余列)

1. 引入依赖

首先添加OpenCSV的Maven依赖,用于解析带分隔符的CSV文件:

<dependency>
    <groupId>com.opencsv</groupId>
    <artifactId>opencsv</artifactId>
    <version>5.6</version> <!-- 使用最新稳定版本即可 -->
</dependency>

2. 核心转换与写入代码

结合你已有的S3客户端和DynamoDB Mapper,实现完整的处理逻辑:

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import com.opencsv.bean.CsvToBeanBuilder;
import com.opencsv.bean.HeaderColumnNameMappingStrategy;

import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.List;

public class S3CsvToDynamoDBProcessor {

    private final AmazonS3 s3Client;
    private final DynamoDBMapper ddbMapper;

    public S3CsvToDynamoDBProcessor(AmazonS3 s3Client, DynamoDBMapper ddbMapper) {
        this.s3Client = s3Client;
        this.ddbMapper = ddbMapper;
    }

    public void processCsv(String s3Bucket, String s3Key) {
        // 获取S3对象并打开输入流,用try-with-resources自动关闭资源
        try (S3Object s3Object = s3Client.getObject(new GetObjectRequest(s3Bucket, s3Key));
             InputStreamReader reader = new InputStreamReader(s3Object.getObjectContent(), StandardCharsets.UTF_8)) {

            // 配置CSV映射策略:只匹配StatusObject的字段,自动忽略多余列
            HeaderColumnNameMappingStrategy<StatusObject> mappingStrategy = new HeaderColumnNameMappingStrategy<>();
            mappingStrategy.setType(StatusObject.class);
            mappingStrategy.setColumnSeparator('|'); // 指定CSV分隔符为|
            mappingStrategy.setTrim(true); // 自动去除表头和字段值前后的空格

            // 解析CSV为StatusObject列表
            List<StatusObject> statusObjects = new CsvToBeanBuilder<StatusObject>(reader)
                    .withMappingStrategy(mappingStrategy)
                    .build()
                    .parse();

            // 逐行写入DynamoDB(也可根据需求改为批量写入)
            for (StatusObject obj : statusObjects) {
                ddbMapper.save(obj); // 替换你之前的load方法,save用于写入/更新数据
            }

        } catch (Exception e) {
            throw new RuntimeException("处理CSV文件失败", e);
        }
    }
}

3. StatusObject类的注解配置

确保你的StatusObject类同时适配DynamoDB和OpenCSV的映射规则,若表头与字段名一致,@CsvBindByName可省略:

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
import com.opencsv.bean.CsvBindByName;

@DynamoDBTable(tableName = "YourStatusTableName") // 替换为你的DynamoDB表名
public class StatusObject {

    @DynamoDBHashKey
    @CsvBindByName(column = "id")
    private String id;

    @DynamoDBAttribute
    @CsvBindByName(column = "name")
    private String name;

    @DynamoDBAttribute
    @CsvBindByName(column = "age")
    private Integer age;

    @DynamoDBAttribute
    @CsvBindByName(column = "height")
    private Double height;

    // 必须保留无参构造函数,DynamoDBMapper和OpenCSV都依赖它
    public StatusObject() {}

    // Getter和Setter方法
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }

    public Double getHeight() { return height; }
    public void setHeight(Double height) { this.height = height; }
}

关键细节说明

  • 自动忽略多余列:HeaderColumnNameMappingStrategy会只映射CSV表头中与StatusObject字段匹配的列,其余列直接跳过,无需额外处理。
  • 分隔符与空格处理:通过setColumnSeparator('|')适配你的CSV格式,setTrim(true)自动清理字段前后的空格(比如示例中12 | abc的空格会被去除)。
  • 类型匹配:确保StatusObject的字段类型与CSV中的数据类型一致,例如CSV中的age是整数,字段需用Integer而非String。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 10:52:42