最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

springboot日期格式化及時差問題分析

 更新時間:2022年12月10日 11:19:51   作者:寂寞旅行  
這篇文章主要介紹了springboot日期格式化,時差問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔

前言

隨著mysql8.0的問世,里面確實(shí)增加了很多功能,例如之前我發(fā)表的文章,數(shù)據(jù)庫層面的遞歸查詢等;不過也隨之而來帶來了一些不兼容的問題,比如group by 報錯,還有就是日期時差問題;

一、mysql中日期字段的正確設(shè)置

create_time timestamp default CURRENT_TIMESTAMP not null comment '創(chuàng)建時間',
update_time timestamp default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '修改時間'

創(chuàng)建時間會自動獲取當(dāng)前時間
修改數(shù)據(jù)的時候,會自動更新 修改時間,免去了每次程序都要設(shè)置的麻煩

二、日期格式化,時差

1. 日期字段返回格式不正確–方案一

例如一個實(shí)體中內(nèi)容如下

@Data
public class AAA{
   //創(chuàng)建時間
    private Date createTime;
    //修改時間
    private Date updateTime;
 }

這樣的話,返回的日期格式就錯誤的,其次也會導(dǎo)致時間會早于數(shù)據(jù)庫的真正時間八小時。我們可以有兩種選擇,直接對當(dāng)前字段設(shè)置日期格式

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")//取日期時使用
   @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")//存日期時使用

也就是這樣

@Data
public class AAA{
   //創(chuàng)建時間
   @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")//取日期時使用
   @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")//存日期時使用
    private Date createTime;
    //修改時間
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")//取日期時使用
   @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")//存日期時使用
    private Date updateTime;
 }

是不是很煩呀每次都要對每個實(shí)體類中的每個日期字段都添加

2.日期字段返回格式不正確–方案二

全局設(shè)置日期格式化的格式,并且全局聲名所有日期 的 補(bǔ)差 八小時,設(shè)置yml即可

spring:
  profiles:
    active: dev
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8

二、日期無法自動填充

由于我已經(jīng)設(shè)置了創(chuàng)建時間的自動填充,和修改時間的自動修改,在數(shù)據(jù)庫層面已經(jīng)沒有問題了,但是當(dāng)我用mybatis的時候,由于insertselective 等的字段非空判斷,導(dǎo)致就不會生成創(chuàng)建時間和修改時間;咋搞?

對于次問題,我們通過攔截器,全局設(shè)置自動填充日期等統(tǒng)一信息,還可以有創(chuàng)建人,修改人等;

1. mybatis-plus

由于mp提供了注解,我們可以通過設(shè)置一個注解就可以搞定填充問題

@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;

2. mybatis 只能靠自己了

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.*;

/**
 * mybatis 攔截器字段自動填充
 **/
@Slf4j
@Component
@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
public class MybatisInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        log.debug("------sqlId------" + mappedStatement.getId());

        // sql類型:insert、update、select、delete
        SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
        Object parameter = invocation.getArgs()[1];
        log.debug("------sqlCommandType------" + sqlCommandType);

        if (parameter == null) {
            return invocation.proceed();
        }

        // 當(dāng)sql為新增或更新類型時,自動填充操作人相關(guān)信息
        if (SqlCommandType.INSERT == sqlCommandType) {

            Field[] fields = getAllFields(parameter);
            for (Field field : fields) {
                try {
                    //注入創(chuàng)建時間
                    if ("createTime".equals(field.getName())) {
                        field.setAccessible(true);
                        field.set(parameter, new Date());
                        field.setAccessible(false);
                    }
                    //注入修改時間
                    if ("updateTime".equals(field.getName())) {
                        field.setAccessible(true);
                        field.set(parameter, new Date());
                        field.setAccessible(false);
                    }
                } catch (Exception e) {
                    log.error("failed to insert data, exception = ", e);
                }
            }
        }
        if (SqlCommandType.UPDATE == sqlCommandType) {

            Field[] fields = getAllFields(parameter);
            for (Field field : fields) {
                try {
                    if ("updateTime".equals(field.getName())) {
                        field.setAccessible(true);
                        field.set(parameter, new Date());
                        field.setAccessible(false);
                    }
                } catch (Exception e) {
                    log.error("failed to update data, exception = ", e);
                }
            }
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        // TODO Auto-generated method stub
    }

    /**
     * 獲取類的所有屬性,包括父類
     *
     * @param object
     * @return
     */
    private Field[] getAllFields(Object object) {
        Class<?> clazz = object.getClass();
        List<Field> fieldList = new ArrayList<>();
        while (clazz != null) {
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        fieldList.toArray(fields);
        return fields;
    }

}

1 MybatisInterceptor
2 MybatisConfiguration
廢話不多說,直接上代碼

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.*;

/**
 * mybatis 攔截器字段自動填充
 **/
@Slf4j
@Component
@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
public class MybatisInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        log.debug("------sqlId------" + mappedStatement.getId());

        // sql類型:insert、update、select、delete
        SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
        Object parameter = invocation.getArgs()[1];
        log.debug("------sqlCommandType------" + sqlCommandType);

        if (parameter == null) {
            return invocation.proceed();
        }

        // 當(dāng)sql為新增或更新類型時,自動填充操作人相關(guān)信息
        if (SqlCommandType.INSERT == sqlCommandType) {

            Field[] fields = getAllFields(parameter);
            for (Field field : fields) {
                try {
                    //注入創(chuàng)建時間
                    if ("createTime".equals(field.getName())) {
                        field.setAccessible(true);
                        field.set(parameter, new Date());
                        field.setAccessible(false);
                    }
                    //注入修改時間
                    if ("updateTime".equals(field.getName())) {
                        field.setAccessible(true);
                        field.set(parameter, new Date());
                        field.setAccessible(false);
                    }
                } catch (Exception e) {
                    log.error("failed to insert data, exception = ", e);
                }
            }
        }
        if (SqlCommandType.UPDATE == sqlCommandType) {

            Field[] fields = getAllFields(parameter);
            for (Field field : fields) {
                try {
                    if ("updateTime".equals(field.getName())) {
                        field.setAccessible(true);
                        field.set(parameter, new Date());
                        field.setAccessible(false);
                    }
                } catch (Exception e) {
                    log.error("failed to update data, exception = ", e);
                }
            }
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        // TODO Auto-generated method stub
    }

    /**
     * 獲取類的所有屬性,包括父類
     *
     * @param object
     * @return
     */
    private Field[] getAllFields(Object object) {
        Class<?> clazz = object.getClass();
        List<Field> fieldList = new ArrayList<>();
        while (clazz != null) {
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        fieldList.toArray(fields);
        return fields;
    }

}
/**
 * mybatis 攔截器注入
 **/
@Configuration
public class MybatisConfiguration {

    /**
     * 注冊攔截器
     */
    @Bean
    public MybatisInterceptor getMybatisInterceptor() {
        return new MybatisInterceptor();
    }
}

總結(jié)

如上就解決了大部分項(xiàng)目中時間的問題,歡迎討論,咨詢~~

到此這篇關(guān)于springboot日期格式化,時差問題的文章就介紹到這了,更多相關(guān)springboot日期格式化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot中的靜態(tài)資源加載順序優(yōu)先級

    springboot中的靜態(tài)資源加載順序優(yōu)先級

    這篇文章主要介紹了springboot中的靜態(tài)資源加載順序優(yōu)先級,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • spring中實(shí)現(xiàn)容器加載完成后再執(zhí)行自己的方法

    spring中實(shí)現(xiàn)容器加載完成后再執(zhí)行自己的方法

    這篇文章主要介紹了spring中實(shí)現(xiàn)容器加載完成后再執(zhí)行自己的方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Java自動化工具Ant的基礎(chǔ)使用教程

    Java自動化工具Ant的基礎(chǔ)使用教程

    這篇文章主要介紹了Java自動化工具Ant的基礎(chǔ)使用教程,例子在Windows系統(tǒng)下操作演示,講解了Ant基本的文件操作和屬性,需要的朋友可以參考下
    2016-02-02
  • ThreadLocal的set方法原理示例解析

    ThreadLocal的set方法原理示例解析

    這篇文章主要為大家介紹了ThreadLocal的set方法原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • SpringBoot整合Jackson的過程詳解

    SpringBoot整合Jackson的過程詳解

    這篇文章給大家介紹了SpringBoot整合Jackson的整合過程,文中通過代碼示例給給大家介紹的非常詳細(xì),并附帶附工具類與使用案例,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-12-12
  • 解決idea默認(rèn)帶的equals和hashcode引起的bug

    解決idea默認(rèn)帶的equals和hashcode引起的bug

    這篇文章主要介紹了解決idea默認(rèn)帶的equals和hashcode引起的bug,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java的IO流實(shí)現(xiàn)文件和文件夾的復(fù)制

    Java的IO流實(shí)現(xiàn)文件和文件夾的復(fù)制

    這篇文章主要為大家詳細(xì)介紹了Java的IO流實(shí)現(xiàn)文件和文件夾的復(fù)制,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 詳細(xì)易懂帶你了解Spring中的注解

    詳細(xì)易懂帶你了解Spring中的注解

    這篇文章主要介紹了詳細(xì)易懂帶你了解Spring中的注解,Spring的一個核心是IOC,是將Bean初始化加載到容器中,Bean是如何加載到容器的,可以使用Spring注解方式或者Spring XML配置方式,需要的朋友可以參考下
    2023-08-08
  • 圖片驗(yàn)證碼概述及實(shí)現(xiàn)步驟

    圖片驗(yàn)證碼概述及實(shí)現(xiàn)步驟

    本文主要介紹了圖片驗(yàn)證碼概述及實(shí)現(xiàn)步驟。具有一定的參考價值,下面跟著小編一起來看下吧
    2017-01-01
  • 深入剖析java中的集合框架

    深入剖析java中的集合框架

    下面小編就為大家?guī)硪黄钊肫饰鰆ava中的集合框架。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-05-05

最新評論

辽宁省| 彰化县| 伊川县| 平谷区| SHOW| 沂南县| 武川县| 额济纳旗| 鄢陵县| 湘阴县| 贺兰县| 花垣县| 中阳县| 新营市| 佳木斯市| 衡阳县| 嵊泗县| 息烽县| 佳木斯市| 贡嘎县| 湘西| 黑河市| 黔西县| 玉树县| 巴里| 忻州市| 萍乡市| 长兴县| 龙泉市| 辽源市| 平顺县| 武功县| 澄城县| 象山县| 玉树县| 平阳县| 渝中区| 青川县| 枞阳县| 青神县| 黄骅市|