基于gin的golang web开发:访问mysql数据库
web开发基本都离不开访问数据库,在Gin中使用mysql数据库需要依赖mysql的驱动。直接使用驱动提供的API就要写很多样板代码。你可以找到很多扩展包这里介绍的是jmoiron/sqlx。另外还有一个用来处理空值的包guregu/null。
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
},
...
]
}
文章出处:基于gin的golang web开发:访问mysql数据库
基于gin的golang web开发:访问mysql数据库的更多相关文章
- 基于gin的golang web开发:mysql增删改查
Go语言访问mysql数据库需要用到标准库database/sql和mysql的驱动.标准库的Api使用比较繁琐这里再引入另一个库github.com/jmoiron/sqlx. go get git ...
- 基于gin的golang web开发:使用数据库事务
在前文介绍访问数据库时介绍了github.com/jmoiron/sqlx包,本文基于这个包使用数据库事务. defer 在使用数据库事务之前,首先需要了解go语言的defer关键字.defer是go ...
- 基于gin的golang web开发:路由
Gin是一个用Golang编写的HTTP网络框架.它的特点是类似于Martini的API,性能更好.在golang web开发领域是一个非常热门的web框架. 启动一个Gin web服务器 使用下面的 ...
- 基于gin的golang web开发:模型验证
Gin除了模型绑定还提供了模型验证功能.你可以给字段指定特定的规则标签,如果一个字段用binding:"required"标签修饰,在绑定时该字段的值为空,那么将返回一个错误.开发 ...
- 基于gin的golang web开发:中间件
gin中间件(middleware)提供了类似于面向切面编程或路由拦截器的功能,可以在请求前和请求之后添加一些自定义逻辑.实际开发中有很多场景会用到中间件,例如:权限验证,缓存,错误处理,日志,事务等 ...
- 基于gin的golang web开发:集成swagger
在前后端分离的项目维护一份完整且及时更新的api文档会极大的提高我们的工作效率,传统项目中接口文档都是由后端开发手写的,这种文档很难保证及时性,久而久之便失去了参考意义.swagger给我们提供了一种 ...
- 基于gin的golang web开发:认证利器jwt
JSON Web Token(JWT)是一种很流行的跨域认证解决方案,JWT基于JSON可以在进行验证的同时附带身份信息,对于前后端分离项目很有帮助. eyJhbGciOiJIUzI1NiIsInR5 ...
- 基于gin的golang web开发:Gin技术拾遗
本文是对前几篇文章的一些补充,主要包含两部分:单元测试和实际项目中使用路由的小问题. 拾遗1:单元测试 Golang单元测试要求代码文件以_test结尾,单元测试方法以Test开头,参数为*testi ...
- 基于gin的golang web开发:实现用户登录
前文分别介绍过了Resty和gin-jwt两个包,Resty是一个HTTP和REST客户端,gin-jwt是一个实现了JWT的Gin中间件.本文将使用这两个包来实现一个简单的用户登录功能. 环境准备 ...
随机推荐
- 057 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 04 案例:求整型数组的数组元素的元素值累加和
057 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 04 案例:求整型数组的数组元素的元素值累加和 本文知识点:求整型数组的数组元素的元素值累加和 案例:求整型数 ...
- TiOps,支持容器,支持多云安全远程运维,疫情期间免费开放,助力远程办公
TiOps,支持多云环境安全远程运维,疫情期间免费对外开放在疫情期间,为减少疾病传染可能性,许多公司的选择了在家远程办公.对于运维来说,既要远程运维,又要保证安全,还要在复杂的IT环境中保持高效,面临 ...
- MeteoInfoLab脚本示例:创建netCDF文件(合并文件)
在MeteoInfoLab中增加了创建netCDF文件并写入数据的功能,这里利用合并多个netCDF文件为一个新的netCDF文件为例.1.创建一个可写入的netCDF文件对象(下面用ncfile表示 ...
- SQl编程存储过程
过程化存储 存储过程,一组为完成特定功能.经过编译后存储在数据库中的SQL语序集 灵活性:存储过程中可以进行流程控制和循环操作来完成复杂的判断和运算 一致性:通过存储过程可以使一些关联的操作一起发生, ...
- 这里有40条提升编程技能小妙招!还有TIOBE 7月份的编程语言排行榜
如何提高编程技能?恐怕很多开发者思考过这个问题.最近,拥有将近 15 年开发经验的软件工程师 Kesk -*- 写了一篇博客,列举了 40 条对其职业生涯有所帮助的事项. 或许,通过以下 40 个 ...
- 【二分图】HEOI2012 朋友圈
题目内容 洛谷链接 在很久很久以前,曾经有两个国家和睦相处,无忧无虑的生活着. 一年一度的评比大会开始了,作为和平的两国,一个朋友圈数量最多的永远都是最值得他人的尊敬,所以现在就是需要你求朋友圈的最大 ...
- Python中while循环初识
基本结构 while 条件: 循环体 基本原理: 1.先判断条件是否为True 2.如果是True进入循环体 3.执行到循环体的底部 4.继续判断条件,条件为True,再次进入 ...
- CPU 运算实现过程
总结 加法运算过程:十进制:1+1=2二进制01+01=10实现过程: 在做加法时CPU内部会调用加法器,实际上加法运算器所做的工作就是按位与操作和进位运算!所谓的进位运算规则和十进制一样满10进一而 ...
- 5G-第五代移动通信系统(5th generation mobile/wireless/cellular system)
通信系统 有意义的信息交流被称为通讯. 自然界:狼嚎.狗叫.虫鸣.鸡叫. 人类社会:说话.眼神.写信.烽火台. 目的:信息的传递. 人类发明电以后,开始使用电来传递信息,特别快. 于是有了电报.电话以 ...
- Java进阶--Java动态代理
JDK version: 1.8 动态代理中所说的"动态", 是针对使用Java代码实际编写了代理类的"静态"代理而言的, 它的优势不在于省去了编写代理类那一点 ...