为基于go的无框架web项目的框架版,采用 gin 和 sqlx 进行框架开发;旨在上手 go 主流框架
github: https://github.com/SwordHarry/gopetstore_v2
template + gin + sqlx + mysql
原采用 gorm,但其具有一定入门门槛和学习成本,其关联查询和关联插入搞不清楚。。。
并且比对起来像 java 的 herbinate,故移用轻小的 sqlx
github: https://github.com/gin-gonic/gin
路由框架,类比起来比较像 node 的 koa 框架;洋葱模型,方便添加中间件,通过 *gin.Context 进行中间件的数据传递,如 logger 等;
个人认为是围绕 controller 层展开的框架,从无框架转移使用起来很平滑,没有什么印象深刻的大坑
guide: http://jmoiron.github.io/sqlx/
github: https://github.com/jmoiron/sqlx
从 guide 中提到的 Go database/sql tutorial
也是值得一看的:http://go-database-sql.org/
sqlx 是在原生 database/sql 之上封装,平滑过渡,model 层 persistence 持久化框架。
但还是逃不过使用 sql 语句,并需要对 sql 语句做一定的修改;
除原生 api 外,提供了 Get
、Select
、NamedQuery
、NamedExec
等方便的框架,省去原生的Scan
过程;
并且,还支持嵌套结构体的赋值,只需要 tag 和 sql column name 一一对应即可,策略为广度优先搜索(很赞的功能了,直接自动化注入,比 gorm 通俗易上手。。。)
但是:需要对 domain 结构体进行 标签 定义并且和 sql 语句中的属性别名进行对应,区分大小写
const getAccountByUsernameSQL = `SELECT USERNAME as userid, EMAIL as email,
CITY as city,STATE as state, ZIP as zip, COUNTRY as country, PHONE as phone
FROM ACCOUNT WHERE USERID = ?`
type Account struct {
UserName string `db:"userid"`
Email string `db:"email"`
FirstName string `db:"firstname"`
LastName string `db:"lastname"`
Status string `db:"status"`
Address1 string `db:"addr1"`
Address2 string `db:"addr2"`
City string `db:"city"`
State string `db:"state"`
Zip string `db:"zip"`
Country string `db:"country"`
Phone string `db:"phone"`
}
// 一条数据
d.Get(a, getAccountByUsernameSQL, userName) // d -> (*sqlx.DB)
// 多条数据
var result []*domain.Account
d.Select(&result, SQLStr, userName)
这样 sqlx 会按照 sql 语句中的属性名,结构体里的 tag 标签名,进行反射配对,最终将值进行赋值,省去了原生go 访问数据库的 scan 过程。
一条数据的查询用 Get
,多条数据的查询用 Select
,并且直接将var result []*domain.Account
将&result
传进去即可
如果数据不是已知规模的,不建议使用 Get 和 Select,因为这两者是直接将全部数据载入到内存再进行赋值的;若数据不知道规模,建议使用 Queryx
或 NamedQuery
api 等
若结构体中出现嵌套结构体或结构体指针,应避免结构体之间出现重名 tag,否则按照 sqlx 广度优先搜索的策略进行赋值,会存在有的属性没有被赋值
通过使用 gin 和 sqlx 框架,对 go 框架开发有一定的熟悉。go web 开发还有很多框架,并不需要每个都熟悉,原持久化层本是采用 gorm 框架,但是学了一通下来发现入门门槛有点高,没有 sql,不太直接,参考 java 的 herbinate。故移用轻巧的 sqlx。go web 开发的第一阶段暂告一段落了,继续加油!