<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
提示:文章寫完後,目錄可以自動生成,如何生成可參考右邊的幫助檔案
隨著mysql8.0的問世,裡面確實增加了很多功能,例如之前我發表的文章,資料庫層面的遞迴查詢等;不過也隨之而來帶來了一些不相容的問題,比如group by 報錯,還有就是日期時差問題;
create_time timestamp default CURRENT_TIMESTAMP not null comment '建立時間', update_time timestamp default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '修改時間'
建立時間會自動獲取當前時間
修改資料的時候,會自動更新 修改時間,免去了每次程式都要設定的麻煩
例如一個實體中內容如下
@Data public class AAA{ //建立時間 private Date createTime; //修改時間 private Date updateTime; }
這樣的話,返回的日期格式就錯誤的,其次也會導致時間會早於資料庫的真正時間八小時。我們可以有兩種選擇,直接對當前欄位設定日期格式
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")//取日期時使用 @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")//存日期時使用
也就是這樣
@Data public class AAA{ //建立時間 @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; }
是不是很煩呀每次都要對每個實體類中的每個日期欄位都新增
全域性設定日期格式化的格式,並且全域性聲名所有日期 的 補差 八小時,設定yml即可
spring: profiles: active: dev jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8
由於我已經設定了建立時間的自動填充,和修改時間的自動修改,在資料庫層面已經沒有問題了,但是當我用mybatis的時候,由於insertselective 等的欄位非空判斷,導致就不會生成建立時間和修改時間;咋搞?
對於次問題,我們通過攔截器,全域性設定自動填充日期等統一資訊,還可以有建立人,修改人等;
1. mybatis-plus
由於mp提供了註解,我們可以通過設定一個註解就可以搞定填充問題
@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(); } // 當sql為新增或更新型別時,自動填充操作人相關資訊 if (SqlCommandType.INSERT == sqlCommandType) { Field[] fields = getAllFields(parameter); for (Field field : fields) { try { //注入建立時間 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(); } // 當sql為新增或更新型別時,自動填充操作人相關資訊 if (SqlCommandType.INSERT == sqlCommandType) { Field[] fields = getAllFields(parameter); for (Field field : fields) { try { //注入建立時間 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(); } }
如上就解決了大部分專案中時間的問題,歡迎討論,諮詢~~
到此這篇關於springboot日期格式化,時差問題的文章就介紹到這了,更多相關springboot日期格式化內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45