1. 概述

在日常开发中,我们经常需要在 java.time.LocalDatejava.sql.Date 之间做转换。尤其是在使用 JPA 或其他 ORM 框架时,这种需求尤为常见。

本文将带你快速掌握几种常用的转换方式,让你在处理日期类型时更加得心应手 ✅


2. 直接转换

最简单的转换方式就是使用 java.sql.Date 提供的静态方法。

2.1 LocalDate 转 java.sql.Date

使用 Date.valueOf() 方法即可完成转换:

Date date = Date.valueOf(LocalDate.now());

或者指定一个具体日期:

Date date = Date.valueOf(LocalDate.of(2019, 1, 10));

⚠️ 注意:如果传入的是 null,会抛出 NullPointerException

2.2 java.sql.Date 转 LocalDate

反过来,使用 toLocalDate() 方法即可:

LocalDate localDate = Date.valueOf("2019-01-10").toLocalDate();

简单粗暴,没有多余操作 ✅


3. 使用 AttributeConverter

3.1 问题背景

虽然 Java 8 引入了强大的 Date/Time API,但在与数据库交互时,尤其是在使用 JPA 时,LocalDate 可能会被映射成 blob 类型,而不是我们期望的 DATE 类型。

为了避免每次都手动转换,我们可以使用 JPA 提供的 AttributeConverter 接口来自动处理转换逻辑。

3.2 实现转换器

下面是一个简单的 AttributeConverter 实现:

@Converter(autoApply = true)
public class LocalDateConverter implements AttributeConverter<LocalDate, Date> {

    @Override
    public Date convertToDatabaseColumn(LocalDate localDate) {
        return Optional.ofNullable(localDate)
          .map(Date::valueOf)
          .orElse(null);
    }

    @Override
    public LocalDate convertToEntityAttribute(Date date) {
        return Optional.ofNullable(date)
          .map(Date::toLocalDate)
          .orElse(null);
    }
}

这个转换器做了两件事:

  • LocalDate 自动转换为 java.sql.Date 存入数据库
  • 从数据库读取时,自动将 java.sql.Date 转回 LocalDate

📌 加上 @Converter(autoApply = true) 后,这个转换器会自动应用到所有 LocalDate 字段上,无需额外配置。


4. LocalDateTime 转 java.sql.Date

有时候我们拿到的是 LocalDateTime,但只想存日期部分(年月日),这时也需要转成 java.sql.Date

⚠️ 注意:java.sql.Date 是不带时间的,只保留日期部分。

4.1 转换方式

由于 LocalDateTime 包含时间信息,我们需要先转成 LocalDate,再转成 java.sql.Date

@Test
void givenALocalDateTime_whenConvertingToSqlDate_thenReturnSqlDateWithoutTime() {
    LocalDateTime givenLocalDateTime = LocalDateTime.parse("2024-05-06T14:02:22.214");
    java.sql.Date expectedSqlDate = java.sql.Date.valueOf("2024-05-06");

    java.sql.Date sqlDate = java.sql.Date.valueOf(givenLocalDateTime.toLocalDate());

    assertThat(sqlDate).isEqualTo(expectedSqlDate);
}

📌 这里要注意:时间部分会被丢弃!


5. 总结

在这篇文章中,我们介绍了两种常用的日期转换方式:

  • ✅ 直接使用 Date.valueOf()toLocalDate() 进行手动转换
  • ✅ 使用 AttributeConverter 实现自动转换,提升代码整洁度

同时也演示了如何将 LocalDateTime 转换为 java.sql.Date,适用于只需要日期部分的场景。

完整代码可以在这里找到 👉 GitHub 项目地址


📌 踩坑提示

  • 不要试图直接把 LocalDateTime 塞进 java.sql.Date,会出问题 ❌
  • 使用 AttributeConverter 时,注意是否真的需要全局生效(autoApply = true)⚠️


原始标题:Converting Between LocalDate and SQL Date | Baeldung