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機制初始化資料庫連線。
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中日期時間型別。
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"
。
訪問一下介面你會發現結果可能並不是你想要的,每一個可空型別的欄位都變成了物件。
{
"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型別。更新後的結構體如下:
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結果,並且當資料為空時也能返回正確的值。
{
"data": [
{
"id": 1,
"name": "role:root",
"description": "超級管理員",
"available": 1,
"create_time": "2020-10-25T03:13:12Z",
"update_time": null
},
...
]
}