微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Spring Boot JPA Hibernate-以毫秒精度存储日期

如何解决Spring Boot JPA Hibernate-以毫秒精度存储日期

Spring Boot版本'2.3.4.RELEASE'
Java 11
org.springframework.boot:spring-boot-starter-jdbc
org.springframework.boot:spring-boot-starter-data-jpa
spring-data-jpa-2.3.4.RELEASE
运行时(MysqLmysql-connector-java)

服务器数据库MariaDB(版本10.5.5-MariaDB)
Java MariaDB连接器J:2.6.0 [稳定]

我试图以毫秒精度将java.sql.Timestamp对象持久保存在Hibernate中。我需要以毫秒为单位将日期保存到数据库。例如:2020-10-08 03:23:38.454。

我的域:

import java.sql.Timestamp;
@Entity
@Data
@Table(name = "date_test")
public class DateTestDomain {
    @Id
    @Column(nullable = false,name = "date",columnDeFinition = "TIMESTAMP(3)")
    @Temporal(TIMESTAMP)
    private Calendar dateTest;
}

我的仓库:

@Repository
public interface DateTestRepo extends JpaRepository<DateTestDomain,Timestamp> {
}

将日期保存到数据库

private final JdbcTemplate db;
...
        long testTime = 1602120218454L;
        Timestamp dateTimeStamp = new Timestamp(testTime);
        db.update("INSERT INTO date_test" + " (date) VALUES( \"" + dateTimeStamp + "\")");

UPD:sql的结果是正确的,因为我需要!!!此方法工作完美: 2020-10-08 03:23:38.454

但是使用休眠/ JPA时结果为FALSE。
调试跟踪:
2020-10-09 22:26:53.120休眠:插入date_test(日期)值(?)
2020-10-09 22:26:53.122跟踪95038 --- [restartedMain] ohtype.descriptor.sql.BasicBinder:绑定参数[1]为[TIMESTAMP]-[2020-10-09 22:26:53.044]

        Calendar calendar = Calendar.getInstance();
        Date date = new Date();
        calendar.setTimeInMillis(date.getTime());
        dateTestDomain.setDateTest(calendar);

        dateTestRepo.save(dateTestDomain);

sql的结果:小数秒总是通过休眠sql插入设置为 .000

2020-10-09 22:26:53.000

请帮助。我需要以毫秒级精度将JPA保存到数据库时间。

UPD:

我尝试使用sql方言:
org.hibernate.dialect.MysqL5InnoDBDialect比org.hibernate.dialect.MysqL55InnoDBDialect比org.hibernate.dialect.MariaDB103Dialect比org.hibernate.dialect.MariaDB105Dialect
没有成功。
UPD 1:
休眠:插入到date_test(时间戳,local_date_time,local_date_timea)值(Now(3),?,?)
2020-10-10 15:33:29.099跟踪44072 --- [restartedMain] ohtype.descriptor.sql.BasicBinder:绑定参数[1]为[TIMESTAMP]-[2020-10-10 15:33:29.051] 2020-10-10 15:33:29.100跟踪44072 --- [restartedMain] ohtype.descriptor.sql.BasicBinder:绑定参数[2]为[TIMESTAMP]-[java.util.GregorianCalendar [time = 1602336809051,areFieldsSet =是的...

结果sql
2020-10-10 15:33:29.101,2020-10-10 13:33:29.000,2020-10-10 15:33:29.000。

还有一个问题:
DB日期:
2020-10-10 16:19:42.578
2020-10-10 16:20:47.000
2020-10-10 16:20:47.888
2020-10-10 16:20:47.892
2020-10-10 16:20:47.896
2020-10-10 16:20:47.900
休眠:从date_test datetestdo0_中选择datetestdo0_.timestamp作为timestam1_0_,其中datetestdo0_.timestamp>?
绑定参数[1]为[TIMESTAMP]-[2020-10-10 16:20:47.893]
2020-10-10 16:20:47.888
2020-10-10 16:20:47.892
2020-10-10 16:20:47.896
2020-10-10 16:20:47.9

jdbcsql
从date_test中选择时间戳记,其中时间戳记>“ 2020-10-10 16:20:47.893”
2020-10-10 16:20:47.896
2020-10-10 16:20:47.900

jpa / hibernate不能以毫秒为单位...

解决方法

自JPA 2.2起,已支持java8日期和时间API。我尚未尝试过是否可以解决您的问题,但是您可以尝试使用java8的LocalDateTime而不是Calendar类型的方法。

替换:

@Id
@Column(nullable = false,name = "date",columnDefinition = "TIMESTAMP")
@Temporal(TIMESTAMP)
private LocalDateTime localDateTime;
,
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(calendar.getTimeInMillis());

尝试使用此方法,而不要使用新的Date()

,

我建议您使用Instant在时间线上建模单个瞬时点。

import java.time.Instant;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        Instant now = Instant.now();
        System.out.println(now);

        // Instant to milliseconds
        System.out.println(now.toEpochMilli());

        // Milliseconds to Instant
        Instant moment = Instant.ofEpochMilli(1602120218454L);
        // Print the default representation i.e. Instant#toString
        System.out.println(moment);
        // Which is same as the following output
        String strTimestampDefaultFormat = moment.toString();
        System.out.println(strTimestampDefaultFormat);

        // Custom representation with milliseconds precision
        String strTimestamp = moment.atOffset(ZoneOffset.UTC)
                .format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSS"));
        System.out.println(strTimestamp);
    }
}

示例运行的输出:

2020-10-08T13:44:46.765240Z
1602164686765
2020-10-08T01:23:38.454Z
2020-10-08T01:23:38.454Z
2020-10-08 01:23:38.454

使用strTimestamp(如上所述),您可以替换

sql.append(" (date) VALUES( \"").append(dateTimeStamp).append("\")");

使用

sql.append(" (date) VALUES( \"").append(strTimestamp).append("\")");

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。