背景
目前golang
操作mysql, 通过原生sql进行操作。
当mysql数据表中字段类型为datetime
即 Y-m-d H:i:s
类型
golang结构体对应字段为string, 解析格式跟数据库类型不一致。
mysql中存储 ` 2012-03-07 13:02:47`
golang解析为 2012-03-07T13:02:47+08:00
, 额外添加了T
+
还有毫秒字段。
如果golang结构体对应字段为time.time, 序列化输出json时, 字段类型也是跟上面一致2012-03-07T13:02:47+08:00
两种方式,都没有达到自己的预期。
所以妥协方案是, 字段定义为time.time类型 字段A, 新添加一个字段B,定义为string类型, 通过A的time.format中间转化一次, 相对比较麻烦。
1 |
|
所以我这次主要解决上面遇到的麻烦事
分析具体问题
为什么结构体中 字段string
类型时间, 和数据库不吻合?
我们发现,在连接mysql时, 有一个parseTime
参数
1 |
|
翻阅官方文档
1 |
|
parseTime=true
改变 数据库DATE
, DATETIME
值的输出类型, 从 []byte/string
类型被改变为time.Time
类型, 像0000-00-00 00:00:00
会被转化为time.Time的零值
再看下我们的配置, parseTime
参数为true, 即我们的datetime
被转化time.time
,
但我们定义的是字符串, 即又被转化为了字符串, 具体转化方案是这样:
DATETIME(Mysql)
—–>time.Time
(golang) ——> string(golang)
, 即这里的time.time到字符串 这一步出现了转化差异。
如果将parseTime
参数置为false, 转化方式为
DATETIME(Mysql)
—–>string(golang)
, 转化无问题。
在大部分程序中, 我们还是需要将时间类型设置为time.Time, 方便我们进行时间到字符串,时间比较等一些操作。
所以我们的问题区间缩小了, 变成了
time.Time
类型,怎么无差异的序列化为json
?
已知,在json序列化时, 如果字段 拥有MarshalJSON
, 则使用该方法序列化此字段。
但是time.Time
是内置函数,我们没办法加上自己的MarshalJSON
。 因此我们考虑别名定义方式, 给自己的变量类型添加 MarshaJSON
方法。
具体操作如下
1 |
|
这样就提高了我们转化时间字段的效率。
参考
- https://github.com/go-sql-driver/mysql