背景
目前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