本篇文章的内容基于 MySQL 和 Sequelize 。
序言
有关时间类型数据的处理其实一直都是一个很让人不爽的地方,在数据库中的存储时间类型默认使用的是 UTC 时间,比我们东八区晚了八个小时,直接使用 UTC 时间显示会让用户摸不着头脑,而如果先取出数据再用 moment 做二次处理显然太麻烦。
Sequelize
Sequelize 是关系型数据库的 ORM ,其作用类似于操作 mongodb 的 mongoose 。
Sequelize 三部分(这里是按我的个人习惯划分)简述:
1、数据库相关宏配置设置,即指定连接的数据库名、操作数据库的用户名和密码,数据库地址,连接池设置等等:
2、数据库中表的定义,这里将表对应为 model :
3、表中具体列的定义,我将其称为 schema,如果你使用过 mongoose 应该很熟悉这个词,但注意这里的 schema 并不是 sequelize 官方文档中的 schema:
以上三个部分及定义了一个完整的数据库结构,数据库操作均可以通过 model 来完成。
问题及解决
言归正传,在上述定义数据库的宏配置时,我们指定了 timezone 为东八区,通过可视化工具如 Navicat 可以看到在数据库中的时间确实是我们想要的,但是查询出来后仍然是 UTC 时间,原因就在于 mysql 数据库和 sequelize 均会对 DATE 类型做处理,timezone 只保证了写入的格式,并没有保证读取的格式。
解决:重新翻了一下 sequelize 的官方文档,发现我们在定义表中列的时候可以设置其 get 和 set 方法,显然这个 get 就是我们想要的,因此重新引入 moment 库对 DATE 类型进行操作:
其实到了这里问题已经基本解决,但是如果你定义了多个表并却其中的列有很多都是 DATE 类型的数据,不断的复制粘贴 get 方法显然不够优雅。
进阶
为了让上述操作更加优雅,我们可以添加一个函数,批量的为 DATE 类型的数据添加 get 方法,但是,大部分情况下时间类型数据的格式为
YYYY-MM-DD HH:mm:ss
可以满足要求,而如果要想指定特殊的时间显示格式呢,显然我们应该允许自定义的 get 方法去设置特殊的时间显示格式。
思路(仍然在定义表中列的时候动手脚):
1、复制原有的所有列定义的对象。
2、遍历每一个表的列
3、在上一步操作内遍历列的每一个数据类型的定义
4、判断 type 类型是都为 DATE,如果是,进一步判断是否已经定义过 get 方法,若已经定义过则不再添加统一的 get 方法,否则添加统一的 get 方法指定统一的时间格式。
结语
解决了一个小问题,完。