Golang中如何获取数据库字段的时间信息
Golang中如何获取数据库字段的时间信息 我在从数据库检索数据时遇到了问题。为什么插入和输出的 created_at 和 updated_at 结果不一致?
插入:2019-03-23 00:00:00
输出:“0001-01-01T00:00:00Z”
相关源代码如下:
结构体:
type Builder struct {
Id int `json:"id"`
Name string `json:"name"`
Created_at time.Time `json:"created_at"`
Updated_at time.Time `json:"updated_at"`
}
数据库:
CREATE TABLE test_types (
id bigint NOT NULL AUTO_INCREMENT,
name varchar(100) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW() ON UPDATE now(),
PRIMARY KEY (id)
);
INSERT INTO test_types (id, name, created_at) VALUES (1, 'Welcome Screen', '2019-03-23 00:00:00');
输出:
{
"id": 1,
"name": "Welcome Screen",
"created_at": "0001-01-01T00:00:00Z",
"updated_at": "0001-01-01T00:00:00Z"
},
Go版本:go1.11.1
数据库:Mariadb 10.3.13
我的代码有什么问题吗?谢谢。
更多关于Golang中如何获取数据库字段的时间信息的实战教程也可以访问 https://www.itying.com/category-94-b0.html
为了正确处理时间和MySQL驱动,您应该在连接字符串中使用parseTime参数。另一个观察是关于使用时间戳字段,这并不是一个很好的选择。如果只在一个时区工作可能没问题,但对于多个时区,请使用datetime或其他等效类型,并让客户端添加其特定时区。简而言之,在服务器上使用UTC时区。
更多关于Golang中如何获取数据库字段的时间信息的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
问题出现在Go结构体字段标签与数据库列名的映射上。Go的数据库/sql包默认使用蛇形命名到驼峰命名的转换,但你的结构体字段使用了蛇形命名(created_at),而数据库列名也是蛇形命名,这可能导致映射失败。
以下是解决方案:
- 明确指定列名映射:
在结构体标签中添加
db标签来明确指定数据库列名:
type Builder struct {
Id int `json:"id" db:"id"`
Name string `json:"name" db:"name"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
}
- 使用SQL别名: 在查询语句中为列指定别名:
rows, err := db.Query(`
SELECT
id,
name,
created_at as createdat,
updated_at as updatedat
FROM test_types
`)
- 完整示例代码:
package main
import (
"database/sql"
"encoding/json"
"fmt"
"log"
"time"
_ "github.com/go-sql-driver/mysql"
)
type Builder struct {
Id int `json:"id" db:"id"`
Name string `json:"name" db:"name"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
}
func main() {
db, err := sql.Open("mysql", "user:password@/dbname")
if err != nil {
log.Fatal(err)
}
defer db.Close()
var builder Builder
err = db.QueryRow(`
SELECT
id,
name,
created_at,
updated_at
FROM test_types WHERE id = ?
`, 1).Scan(
&builder.Id,
&builder.Name,
&builder.CreatedAt,
&builder.UpdatedAt,
)
if err != nil {
log.Fatal(err)
}
jsonData, _ := json.Marshal(builder)
fmt.Println(string(jsonData))
}
- 使用结构体扫描库:
考虑使用
sqlx库来简化映射:
import "github.com/jmoiron/sqlx"
type Builder struct {
Id int `json:"id" db:"id"`
Name string `json:"name" db:"name"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
}
var builder Builder
err = sqlx.Get(db, &builder, "SELECT * FROM test_types WHERE id = ?", 1)
主要问题是命名约定不匹配。Go的数据库驱动通常期望结构体字段使用驼峰命名(如CreatedAt),而数据库列使用蛇形命名(如created_at)。通过明确指定映射关系可以解决这个问题。

