在Hibernate中,@Temporal注解有什么用途?

142
Hibernate文档针对@Temporal注释提供以下信息:
在普通的Java API中,时间的精度未被定义。当处理时间数据时,您可能想要在数据库中描述预期的精度。时间数据可以具有日期、时间或时间戳精度(即实际日期、仅时间或两者)。使用@Temporal注释来微调它。
“时间的精度未被定义”是什么意思?什么是“时间”的数据及其精度?它如何进行微调?

6
如果您在实体属性中使用日历作为数据类型,在普通的Java代码中打印的信息可能会很多,这些信息在保存到数据库时并不必要。如果您只想存储时间戳、日期或者时间,您可以在实体类中对应的日历属性上添加 @Temporal(TemporalType.TIMESTAMP)、@Temporal(TemporalType.DATE) 或者 @Temporal(TemporalType.TIME) 注解来进行设置。 - user3487063
5
自 Hibernate 5 开始,您不需要也不应该在新代码中使用 @Temporal。它是用于注释 DateCalendar 字段的,但这些类设计不佳且已经过时。相反,应该使用来自 java.time, 现代 Java 日期和时间 API 的类。它们内置了预期的精度,并且您不需要使用该注释与它们一起使用。 - Ole V.V.
8个回答

142

此注解必须指定为类型为java.util.Datejava.util.Calendar的持久字段或属性。它只能用于这些类型的字段或属性。

Temporal注解可以与Basic注解、Id注解或ElementCollection注解(当元素集合值是这种时间类型时)一起使用。

在普通的Java API中,时间的精确度未定义。处理时间数据时,您可能想在数据库中描述预期的精度。时间数据可以具有DATE、TIME或TIMESTAMP精度(即实际日期、仅时间或两者)。使用@Temporal注解来微调它。

时间数据是与时间相关的数据。例如,在内容管理系统中,文章的创建日期和最后更新日期是时间数据。在某些情况下,时间数据需要精度,您想在数据库表中存储精确的日期/时间或两者(TIMESTAMP)。

核心Java API未指定时间精度。@Temporal是一个JPA注解,可在时间戳和java.util.Date之间进行转换。它还会将时间戳转换为时间。例如,在下面的代码片段中,@Temporal(TemporalType.DATE) 删除时间值并仅保留日期。

@Temporal(TemporalType.DATE)
private java.util.Date creationDate;

根据Javadoc文档,

使用注释在查询方法参数上声明适当的{@code TemporalType}。请注意,此注释仅可用于具有默认TemporalType.DATE的{@link Date}类型参数。

[以上信息来自各种来源]


1
为什么我不能将它与Java类型Timestamp一起使用? - powder366
3
如果你只是使用TemporalType.TIMESTAMP...那么使用这个注释有什么意义呢?使用日期似乎可以很好地达到这个目的,没有必要使用它。 - Alkanshel
1
我该如何以“yyyy-MM-dd”的格式将数据存储到MySql数据库中? - Shantaram Tupe
1
@shantaram_t 这个链接可能对你有帮助:http://stackoverflow.com/questions/18364789/format-datetime - Ankur Singhal
1
我有一个输入:02/10/2017,想要将其转换为 2017-10-02 或者 2017/10/02 - Shantaram Tupe
显示剩余2条评论

70

@Temporal 是一个 JPA 注解,可用于将以下列项之一存储在数据库表中:

  1. DATE (java.sql.Date)
  2. TIME (java.sql.Time)
  3. TIMESTAMP (java.sql.Timestamp)

通常情况下,当我们在类中声明 Date 字段并尝试将其存储时,它会作为 TIMESTAMP 存储在数据库中。

@Temporal
private Date joinedDate;

以上代码将存储类似于08-07-17 04:33:35.870000000 PM的值。

如果我们想要在数据库中仅存储日期
我们可以使用/定义TemporalType

@Temporal(TemporalType.DATE)
private Date joinedDate;

这一次,它会将08-07-17存储在数据库中。

除了@Temporal之外,还有其他一些属性可以根据需要使用。


默认值为TemporalType.DATE。不知道为什么提供了带有时间部分的非注释属性值。 - Simon Logic
如果两个日期相同,则以上方面将起作用(TemporalType.DATE)。 - Lova Chittumuri
Hibernate中的@Temporal注解有什么用途? - Lova Chittumuri

12

时间类型是一组基于时间的类型,可用于持久状态映射。

支持的时间类型列表包括三个java.sql类型java.sql.Datejava.sql.Timejava.sql.Timestamp,以及两个java.util类型java.util.Datejava.util.Calendar

java.sql类型完全无需考虑。它们就像任何其他简单映射类型一样,并不需要任何特殊考虑。

然而,这两个java.util类型需要额外的元数据来指示与JDBC驱动程序通信时使用哪个JDBC java.sql类型。这可以通过使用@Temporal注释并将JDBC类型指定为TemporalType枚举类型的值来完成。

有三个枚举值DATE、TIME和TIMESTAMP,代表每个java.sql类型。


7

如果你只是要一个简短的答案:

在使用java.util.Date时,Java并不知道如何直接关联SQL类型。这就是@Temporal发挥作用的时候。它被用来指定所需的SQL类型。

来源:Baeldung


6

我使用的是Hibernate 5.2,@Temporal不再是必需的。
java.util.datesql.datetime.LocalDate会以适当的数据类型(Date/timestamp)存储到数据库中。


如果我们只想使用Hibernate 5.x保存日期,那么解决方案是什么? - Kms
3
Java 8 LocalDate的使用Java 8引入了新的日期时间API,其中之一是LocalDate类。LocalDate表示不带时区的日期,如2023-03-22。要创建一个LocalDate对象,可以使用now()方法获取当前日期,或使用of()方法指定年、月、日参数。例如:// 获取当前日期 LocalDate now = LocalDate.now(); // 创建指定日期的对象 LocalDate date = LocalDate.of(2023, 3, 22);可以使用getYear()、getMonth()和getDayOfMonth()等方法获取日期的各个部分,也可以使用withXXX()方法设置日期的某个部分。例如:int year = date.getYear(); Month month = date.getMonth(); int day = date.getDayOfMonth(); LocalDate newDate = date.withYear(2024).withMonth(4).withDayOfMonth(1);此外,LocalDate还提供了许多常用的操作,如加减天数、比较日期、格式化日期等。例如:LocalDate tomorrow = today.plusDays(1); LocalDate yesterday = today.minusDays(1); int result = today.compareTo(otherDate); String formattedDate = today.format(DateTimeFormatter.ISO_DATE);总的来说,Java 8中的LocalDate类提供了方便且易于使用的日期处理功能,适用于许多应用程序。 - Josh

4
@Temporal是Hibernate JPA注解之一,仅应在java.util.Date或java.util.Calendar上设置。 它有助于将日期和时间值从Java对象转换为兼容的数据库类型,并将其检索回应用程序。 支持;
@Temporal(TemporalType.TIMESTAMP)
@Temporal(TemporalType.DATE)
@Temporal(TemporalType.TIME)

1
这并没有为现有的答案增加任何新内容! - Chacko

3

使用这个

@Temporal(TemporalType.TIMESTAMP)
@Column(name="create_date")
private Calendar createDate;

public Calendar getCreateDate() {
    return createDate;
}

public void setCreateDate(Calendar createDate) {
    this.createDate = createDate;
}

这并没有为现有的答案增加任何新内容! - Chacko

1
我们使用@Temporal注释将日期、时间或两者都插入数据库表中。使用TemporalType,我们可以将日期、时间或两者都插入表中。
@Temporal(TemporalType.DATE) // insert date
@Temporal(TemporalType.TIME) // insert time
@Temporal(TemporalType.TIMESTAMP) // insert  both time and date.

谢谢,但我们为什么要使用它? - Pratik Ambani
这并没有为现有的答案增加任何新内容! - Chacko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接