Converting Between LocalDate and SQL Date – 在LocalDate和SQL Date之间进行转换

最后修改: 2019年 1月 16日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this quick tutorial, we’ll learn how to convert between java.time.LocalDate and java.sql.Date.

在这个快速教程中,我们将学习如何在java.time.LocalDatejava.sql.Date之间转换。

2. Direct Conversion

2.直接转换

To convert from LocalDate to java.sql.Date, we can simply use the valueOf() method available in java.sql.Date. Likewise, to convert the current date, we can use:

要将LocalDate转换为java.sql.Date,我们可以简单地使用valueOf()方法,该方法在java.sql.Date同样地,要转换当前日期,我们可以使用。

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

Or, any other specific date:

或者,任何其他具体日期。

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

Moreover, valueOf() throws NullPointerException in case of a null argument.

此外,valueOf()在参数为null的情况下会抛出NullPointerException

Now, let’s convert from java.sql.Date to LocalDate. For that, we can use the toLocalDate() method:

现在,让我们从java.sql.Date转换到LocalDate。为此,我们可以使用toLocalDate()方法。

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

3. Using an AttributeConverter

3.使用一个AttributeConverter

First, let’s understand the problem.

首先,让我们了解一下这个问题。

Java 8 has lots of useful features, including the Date/Time API.

Java 8 有很多有用的功能,包括Date/Time API

However, using it with some databases or persistence frameworks requires a bit more work than expected. For instance, JPA will map the LocalDate property into a blob instead of the java.sql.Date object. As a result, the database won’t recognize the LocalDate property as a Date type.

然而,在某些数据库或持久化框架中使用它,需要比预期多做一些工作。例如,JPA会将LocalDate属性映射为一个blob而不是java.sql.Date对象。因此,数据库不会将LocalDate属性识别为Date类型。

In general, we don’t want to perform an explicit conversion between the LocalDate and Date.

一般来说,我们不希望在LocalDateDate之间进行明确的转换。

For example, suppose we have an entity object with a LocalDate field. When persisting this entity, we need to tell the persistence context how to map the LocalDate into the java.sql.Date.

例如,假设我们有一个带有LocalDate字段的实体对象。在持久化这个实体时,我们需要告诉持久化上下文如何将LocalDate映射到java.sql.Date

Let’s apply a simple solution by creating an AttributeConverter class:

让我们应用一个简单的解决方案,创建一个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);
    }
}

As we can see, the AttributeConverter interface accepts two types: LocalDate and Date in our case.

我们可以看到,AttributeConverter接口接受两种类型。LocalDateDate在我们的例子中。

In short, the convertToDatabaseColumn() and convertToEntityAttribute()  methods will take care of the conversion process. Inside of the implementations, we use Optional to easily handle possible null references.

简而言之,convertToDatabaseColumn()convertToEntityAttribute() 方法将负责转换过程。在实现内部,我们使用Optional来轻松处理可能的null引用。

Moreover, we’re also using the @Converter annotation. With the autoApply=true property, the converter will be applied to all mapped attributes of the entity’s type.

此外,我们也在使用@Converter注解。通过autoApply=true属性,转换器将被应用到实体类型的所有映射属性中。

4. Conclusion

4.结论

In this quick tutorial, we showed two ways to convert between java.time.LocalDate and java.sql.Date. Moreover, we presented examples using direct conversion and using a custom AttributeConverter class.

在这个快速教程中,我们展示了在java.time.LocalDatejava.sql.Date.之间转换的两种方法。此外,我们还介绍了使用直接转换和使用自定义AttributeConverter类的例子。

As usual, the complete code for this article is available over on GitHub.

像往常一样,本文的完整代码可以在GitHub上找到