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

从数据库导出数据生成CSV为空及日期字段拆分问题求解

核心问题根因(CSV文件为空)

  • DTO构造方法为空:ClientDto 中接收ClientEntity的构造方法public ClientDto(ClientEntity clientEntity) {}没有任何字段赋值逻辑,getAll()方法将查询到的ClientEntity转DTO后,所有字段都是默认空值,输出自然为空。
  • IO流未刷缓存、未关闭:Scheduler里的Writer写完内容后没有调用flush()刷缓冲区,也没有close()释放资源,内存中的内容没有写入磁盘,就算数据正确也会生成空文件。
  • 方法调用不匹配:Scheduler里调用的是clientService.getAll(),该方法走的是JpaRepository自带的findAll()查全表,你自定义的带过滤条件的getAllByRegDate()根本没被调用,如果全表无数据输出自然为空。另外查询方法上加了@Modifying注解,该注解仅用于增删改操作,查询方法加了会导致逻辑异常。
  • 冗余映射(非直接原因):Scheduler里clientService.getAll().stream().map(ClientDto::new).collect(Collectors.toList())属于多余操作,getAll()已经返回了ClientDto列表,不需要二次转换。

修复步骤

1. 补全ClientDto的构造方法

public ClientDto(ClientEntity clientEntity) {
    this.id = clientEntity.getId();
    this.created_dt = clientEntity.getCreated_dt();
    this.username = clientEntity.getUsername();
    this.name = clientEntity.getName();
    this.amount = clientEntity.getAmount();
    this.status = clientEntity.getStatus();
    this.account = clientEntity.getAccount();
    this.external_id = clientEntity.getExternal_id();
    this.external_status = clientEntity.getExternal_status();
}

2. 修正Scheduler的IO逻辑,用try-with-resources自动管理流

@Scheduled(fixedRate = 5000)
public void downloadBlockedClients() {
    String fileName = "select.csv";
    // try-with-resources会自动关闭流、刷缓冲区,无需手动操作
    try (FileOutputStream outputStream = new FileOutputStream(fileName);
         Writer writer = Channels.newWriter(outputStream.getChannel(), "UTF-8")) {
        // 如果需要用自定义条件的查询,这里改成 clientService.getAllByRegDateAfter()
        List<ClientDto> clientDtos = clientService.getAll();
        writer.append("id|created_dt|username|name|amount|status|account|external_id|external_status").append("\n");
        for (ClientDto dto : clientDtos) {
            writer.append(dto.toString()).append("\n");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

3. 移除Repository查询方法的无效注解

删掉getAllByRegDate()上的@Modifying和@Transactional注解,这两个注解仅用于增删改操作,查询不需要。


created_dt拆分日期、时间两列实现

  1. 首先将ClientEntity的created_dt字段类型从LocalDate改为LocalDateTime,LocalDate仅存储日期没有时间信息,无法拆分:
@Column(name = "created_dt")
private LocalDateTime created_dt;
  1. ClientDto新增两个字段,修改构造方法和toString逻辑:
// 新增字段
private LocalDate createdDate;
private LocalTime createdTime;

// 构造方法里补充赋值逻辑,以ClientEntity构造方法为例
public ClientDto(ClientEntity clientEntity) {
    this.id = clientEntity.getId();
    // 拆分日期时间
    this.createdDate = clientEntity.getCreated_dt().toLocalDate();
    this.createdTime = clientEntity.getCreated_dt().toLocalTime();
    // 其他字段赋值省略...
}

// 修改toString方法,加入两个新字段
@Override
public String toString() {
    return "" + id + "|" + createdDate + "|" + createdTime + "|" + username + "|" + name +
            "|" + amount + "|" + status + "|" + account + "|" + external_id + "|" + external_status;
}
  1. 修改CSV表头,新增两列:
writer.append("id|created_date|created_time|username|name|amount|status|account|external_id|external_status").append("\n");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 01:27:03