springboot 2.1.7 + mysql5.6 棄用 Calendar類型字段

緣由:在使用Calendar作爲字段類型時,每進行一次findById()操做返回的數據的值都比實際值要大一點。更新後再調用查詢,還會再大一點。也就是說:若是咱們用Calendar作爲字段類型,那麼該字段會在程序運行時會靜悄悄的增大。java

代碼準備

示例代碼很簡單:咱們只須要準備兩個類,一個實體,一個數據訪問對象。mysql

Student.javagit

package com.example.demo;

import org.hibernate.annotations.CreationTimestamp;

import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Calendar;

@Entity
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    
    @CreationTimestamp
    private Calendar applyTime;
    
    @CreationTimestamp
    private Timestamp applyTimestamp;

    // 省略構造函數及setter/getter
}

爲了測試代碼更簡單,咱們爲applyTimeapplyTime加入CreationTimestamp註解。讓其自動生成。github

刪除自動時間戳並不會影響測試結果
package com.example.demo;

import org.springframework.data.repository.CrudRepository;

public interface StudentRepository extends CrudRepository<Student, Long> {
}

測試代碼

package com.example.demo;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest
@RunWith(SpringRunner.class)
public class StudentRepositoryTest {
    private static final Logger logger = LoggerFactory.getLogger(StudentRepositoryTest.class);
    @Autowired StudentRepository studentRepository;

    @Test
    public void test() {
        Student student = new Student();
        studentRepository.save(student);

        Student student1 = studentRepository.findById(student.getId()).get();
        System.out.println(student1.getApplyTime().getTimeInMillis());
        System.out.println(student1.getApplyTimestamp().getTime());
   }
}

結果以下:spring

1566119784000
1566090984000

clipboard.png

可見,使用Calendar類型獲取值較Timestamp類型的自動增長了。若是此時保存實體,則此增長的值將被自動寫入數據表。sql

github: https://github.com/mengyunzhi...
stackoverflow: https://stackoverflow.com/que...數據庫

結論

Calendar類型在spring-boot 2.1.7版本中應該暫時棄用,轉而使用TimestampLocalDateTimesegmentfault

老項目升級

若是你也是在版本的基礎上升的級,那麼須要處理同樣時區的問題。由於一樣的數據CalendarTimestamp最終存到數據庫中的值是不一致的。其中Calendar存的是加入了時區之後的值,Timestamp存的是原始值:app

clipboard.png

幸運的是:兩個類型映射到mysql中的類型均是datetime,這爲咱們下降了升級的難度。函數

變動實體映射類型

@CreationTimestamp
    private Timestamp applyTime;

老數據-8時處理

update student set apply_time = SUBTIME(apply_time, '8:00');
相關文章
相關標籤/搜索