web开发基本都离不开访问数据库,在Gin中使用mysql数据库需要依赖mysql的驱动。直接使用驱动提供的API就要写很多样板代码。你可以找到很多扩展包这里介绍的是jmoiron/sqlx。另外还有一个用来处理空值的包guregu/null。
1 2 3
| go get github.com/go-sql-driver/mysql go get gopkg.in/guregu/null.v4 go get github.com/jmoiron/sqlx
|
连接数据库
jmoiron/sqlx包为database/sql提供了很多扩展方法,例如Select可以直接把查询结果映射为结构体,不在需要对每一列进行绑定。使用jmoiron/sqlx连接数据库的方法和mysql驱动提供的方法是一样的,可以直接调用sqlx.Connect并传入连接字符串。这里使用go语言init机制初始化数据库连接。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package db
import ( _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" "log" )
var Db *sqlx.DB
func init() { db, err := sqlx.Connect("mysql", "...?parseTime=true") if err != nil { log.Panicln("db err: ", err.Error()) } db.SetMaxOpenConns(20) db.SetMaxIdleConns(20) Db = db }
|
连接字符串中设置parseTime=true是为了解析mysql中日期时间类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| type SysRole struct { Id int64 `json:"id"` Name sql.NullString `json:"name"` Description sql.NullString `json:"description"` Available sql.NullInt32 `json:"available"` CreateTime sql.NullTime `json:"create_time" db:"create_time"` UpdateTime sql.NullTime `json:"update_time" db:"update_time"` }
func main() { r := gin.Default() r.GET("/test", func(c *gin.Context) { var sysRole []SysRole
dataSql := ` select id, name, description, available, create_time, update_time from sys_role ` err := db.Db.Select(&sysRole, dataSql) if err != nil { panic(`select sys_role err: ` + err.Error()) }
c.JSON(200, gin.H{ "data": sysRole, }) }) r.Run(":9001") }
|
在go语言中int、string之类的类型是不可以为空的,sql.NullXXX类型代表了数据库中的可空类型。还要注意一下CreateTime字段的标签,如果表的列名和结构体字段名不一样的话就要添加db标签db:"create_time"。
访问一下接口你会发现结果可能并不是你想要的,每一个可空类型的字段都变成了对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| { "data": [ { "id": 1, "name": { "String": "role:root", "Valid": true }, "description": { "String": "超级管理员", "Valid": true }, "available": { "Int32": 1, "Valid": true }, "create_time": { "Time": "2020-10-25T03:13:12Z", "Valid": true }, "update_time": { "Time": "2020-10-25T03:13:12Z", "Valid": true } } ... ] }
|
解决空值的问题
使用guregu/null包可以解决空值的问题,guregu/null为数据库和JSON提供了可空的数据类型,可以替换掉所有sql.NullXXX类型。更新后的结构体如下:
1 2 3 4 5 6 7 8
| type SysRole struct { Id int64 `json:"id"` Name null.String `json:"name"` Description null.String `json:"description"` Available null.Int `json:"available"` CreateTime null.Time `json:"create_time" db:"create_time"` UpdateTime null.Time `json:"update_time" db:"update_time"` }
|
再次访问接口会看到熟悉的JSON结果,并且当数据为空时也能返回正确的值。
1 2 3 4 5 6 7 8 9 10 11 12 13
| { "data": [ { "id": 1, "name": "role:root", "description": "超级管理员", "available": 1, "create_time": "2020-10-25T03:13:12Z", "update_time": null }, ... ] }
|