Go语言Gin框架中使用MySQL数据库的三种方式
作者:浮尘笔记
本文演示在Gin框架中通过三种方式实现增删改查的操作,数据表结构如下:
CREATE TABLE `users` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', `user_no` bigint(20) unsigned NOT NULL COMMENT '用户编号', `name` varchar(255) NOT NULL DEFAULT '' COMMENT '用户姓名', `age` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '用户年龄', `address` varchar(255) NOT NULL DEFAULT '' COMMENT '地址', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间', `update_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), UNIQUE KEY `key_user_no` (`user_no`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
原生SQL操作
在Gin框架中使用MySQL的最简单的方式就是直接处理SQL语句,记得引入 _ "github.com/go-sql-driver/mysql"
。
代码如下:
//公共方法封装 package dbUtil import ( "database/sql" "fmt" "github.com/gin-gonic/gin" _ "github.com/go-sql-driver/mysql" "net/http" "strconv" ) var tableName = "users" //数据表名 var result ResponseData //响应结果数据 // 统一返回数据的结构体 type ResponseData struct { Code int `json:"code"` Message string `json:"message"` Data interface{} `json:"data"` } func showSuccess(c *gin.Context, data interface{}) { result.Code = http.StatusOK result.Message = "操作成功" result.Data = data c.JSON(http.StatusOK, result) return } func showError(c *gin.Context, message string) { result.Code = http.StatusBadRequest result.Message = message result.Data = nil c.JSON(http.StatusOK, result) return } // 使用原生SQL语句 // go-sql-driver地址:https://github.com/go-sql-driver/mysql var sqlDb *sql.DB //数据库连接db // 初始化 func init() { //打开数据库 //parseTime:时间格式转换(查询结果为时间时,是否自动解析为时间); //loc=Local:MySQL的时区设置 sqlStr := "root:rx123456@tcp(127.0.0.1:3306)/gin_demo?charset=utf8&parseTime=true&loc=Local" var err error sqlDb, err = sql.Open("mysql", sqlStr) if err != nil { fmt.Println("数据库打开失败:", err) return } //测试与数据库建立的连接,非必要(校验连接是否正确) err = sqlDb.Ping() if err != nil { fmt.Println("数据库连接失败:", err) return } } // 用户结构体 type sqlUserData struct { Id int `json:"id"` UserNo int `json:"user_no"` Name string `json:"name"` Age int `json:"age"` Address string `json:"address"` Remarks string `json:"remarks"` } func MysqlInsertData(c *gin.Context) { /* //请求参数 { "user_no":1001, "name":"张三", "age":18, "address":"北京昌平" } */ var user sqlUserData err := c.Bind(&user) if err != nil { showError(c, fmt.Sprint(err)) return } sqlStr := "insert into " + tableName + "(user_no, name, age, address) values (?,?,?,?)" ret, err := sqlDb.Exec(sqlStr, user.UserNo, user.Name, user.Age, user.Address) if err != nil { fmt.Printf("insert failed, err:%v\n", err) showError(c, fmt.Sprint(err)) return } newDataId, _ := ret.LastInsertId() showSuccess(c, "新增的结果id:"+strconv.Itoa(int(newDataId))) }
func MysqlGetUserList(c *gin.Context) { name := c.Query("name") sqlStr := "select id,user_no,name,age,address from " + tableName + " where name=?" rows, err := sqlDb.Query(sqlStr, name) if err != nil { showError(c, fmt.Sprint(err)) return } defer rows.Close() userList := make([]sqlUserData, 0) for rows.Next() { var user sqlUserData rows.Scan(&user.Id, &user.UserNo, &user.Name, &user.Age, &user.Address) if user.Age >= 18 { user.Remarks = "已成年" } else { user.Remarks = "未成年" } userList = append(userList, user) } showSuccess(c, userList) }
func MysqlGetUserInfo(c *gin.Context) { id := c.Query("id") sqlStr := "select id,user_no,name,age,address from " + tableName + " where id=?" var user sqlUserData err := sqlDb.QueryRow(sqlStr, id).Scan(&user.Id, &user.UserNo, &user.Name, &user.Age, &user.Address) if err != nil { showError(c, fmt.Sprint(err)) return } showSuccess(c, user) }
func MysqlUpdateData(c *gin.Context) { /* //请求参数 { "id":1, "age":13, "address":"河北" } */ var user sqlUserData err := c.Bind(&user) if err != nil { showError(c, fmt.Sprint(err)) return } sqlStr := "update " + tableName + " set age=? ,address=? where id=?" ret, err := sqlDb.Exec(sqlStr, user.Age, user.Address, user.Id) if err != nil { fmt.Printf("update failed, err:%v\n", err) showError(c, fmt.Sprint(err)) return } res, _ := ret.RowsAffected() showSuccess(c, "受影响的行数:"+strconv.Itoa(int(res))) }
func MysqlDeleteData(c *gin.Context) { id := c.Query("id") var count int //先查询 sqlStr := "select count(*) from " + tableName + " where id=?" err := sqlDb.QueryRow(sqlStr, id).Scan(&count) if count <= 0 || err != nil { showError(c, "数据不存在") return } //再删除 delStr := "delete from " + tableName + " where id=?" ret, err := sqlDb.Exec(delStr, id) if err != nil { fmt.Printf("delete failed, err:%v\n", err) showError(c, fmt.Sprint(err)) return } res, _ := ret.RowsAffected() showSuccess(c, "受影响的行数:"+strconv.Itoa(int(res))) }
XORM
xorm是一个Go语言的ORM库,通过它可以很方便的操作数据库。它的设计重点是高性能和易用性。XORM支持多种数据库,包括MySQL、PostgreSQL、SQLite、Oracle和SQL Server,并提供了丰富的查询语言。XORM还支持事务和缓存机制,可以提高数据库操作的性能。添加依赖:go get github.com/go-xorm/xorm
ORM,即pobject-RelationlMapping,它的作用是在关系型数据库和对象之间作一个映射,这样我们在具体操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它就可以了。
比较好的Go语言ORM包括:xorm与gorm
下面是代码实现:
package dbUtil import ( "fmt" "github.com/gin-gonic/gin" _ "github.com/go-sql-driver/mysql" "github.com/go-xorm/xorm" "strconv" "time" ) var myXorm *xorm.Engine // 定义结构体(xorm支持双向映射);如果表不存在,则会自动创建 type users struct { Id int64 `xorm:"pk autoincr" json:"id"` //指定主键并自增 UserNo int `xorm:"unique" json:"user_no"` Name string `json:"name"` Age int `json:"age"` Address string `json:"address"` CreateTime time.Time `xorm:"created" json:"create_time"` UpdateTime time.Time `xorm:"updated" json:"update_time"` } func init() { sqlStr := "root:rx123456@tcp(127.0.0.1:3306)/gin_demo?charset=utf8&parseTime=true&loc=Local" var err error //创建数据库引擎 myXorm, err = xorm.NewEngine("mysql", sqlStr) if err != nil { fmt.Println("数据库连接失败:", err) } //创建或者同步表,表名称是users //如果数据表不存在,会根据users结构体自动创建 err = myXorm.Sync(new(users)) if err != nil { fmt.Println("数据表同步失败:", err) } } func XormGetUserList(c *gin.Context) { name := c.Query("name") var user []users err := myXorm.Where("name=?", name).And("age>20").Limit(10, 0).Asc("age").Find(&user) if err != nil { showError(c, fmt.Sprint(err)) return } showSuccess(c, user) } func XormGetUserInfo(c *gin.Context) { id := c.Query("id") var user []users err := myXorm.Where("id=?", id).Find(&user) if err != nil { showError(c, fmt.Sprint(err)) return } if len(user) == 0 { showSuccess(c, nil) } showSuccess(c, user[0]) } func XormInsertData(c *gin.Context) { /* //请求参数 { "user_no":1001, "name":"张三", "age":18, "address":"北京昌平" } */ var user users err := c.Bind(&user) if err != nil { showError(c, fmt.Sprint(err)) return } affected, err := myXorm.Insert(user) if err != nil || affected <= 0 { fmt.Printf("insert failed, err:%v\n", err) showError(c, fmt.Sprint(err)) return } showSuccess(c, "受影响的行数:"+strconv.Itoa(int(affected))) } func XormUpdateData(c *gin.Context) { /* //请求参数 { "id":1, "age":13, "address":"河北" } */ var u users err := c.Bind(&u) if err != nil { showError(c, fmt.Sprint(err)) return } //先查找 var user []users err = myXorm.Where("id=?", u.Id).Find(&user) //fmt.Println(myXorm.NewSession().LastSQL()) if err != nil { showError(c, fmt.Sprint(err)) return } if len(user) == 0 { showError(c, "数据不存在") return } //再修改 affected, err := myXorm.Where("id=?", u.Id).Update(&users{ Age: u.Age, Address: u.Address, }) if err != nil { showError(c, fmt.Sprint(err)) return } showSuccess(c, "受影响的行数:"+strconv.Itoa(int(affected))) } func XormDeleteData(c *gin.Context) { id := c.Query("id") //先查找 var user []users err := myXorm.Where("id=?", id).Find(&user) if err != nil { showError(c, fmt.Sprint(err)) return } if len(user) == 0 { showError(c, "数据不存在") return } //再删除 affected, err := myXorm.Where("id=?", id).Delete(&users{}) if err != nil { showError(c, fmt.Sprint(err)) return } showSuccess(c, "受影响的行数:"+strconv.Itoa(int(affected))) }
GORM
GORM是Go语言中最受欢迎的ORM框架之一。它具有易于使用的API和灵活的查询语言,支持多种类型的数据库,包括MySQL、PostgreSQL、SQLite和SQL Server。GORM还提供了自动迁移功能,可以在应用程序启动时自动创建数据库表和字段。
使用方法:添加依赖 go get gorm.io/gorm
和 go get gorm.io/driver/mysql
实现代码如下:
package dbUtil import ( "fmt" "github.com/gin-gonic/gin" _ "github.com/go-sql-driver/mysql" "gorm.io/driver/mysql" "gorm.io/gorm" "time" ) var gormDB *gorm.DB // 定义结构体 // 特别注意:结构体名称为:user,创建的表的名称为:users type user struct { Id int `gorm:"primaryKey;autoIncrement" json:"id"` //指定主键并自增 UserNo int `gorm:"unique" json:"user_no"` Name string `gorm:"type:varchar(256);not null" json:"name"` Age int `gorm:"type:tinyint(4);not null" json:"age"` Address string `gorm:"type:varchar(256);not null" json:"address"` CreateTime time.Time `json:"create_time"` UpdateTime time.Time `json:"update_time"` } func init() { var err error sqlStr := "root:rx123456@tcp(127.0.0.1:3306)/gin_demo?charset=utf8mb4&parseTime=true&loc=Local" gormDB, err = gorm.Open(mysql.Open(sqlStr), &gorm.Config{}) //配置项中预设了连接池 ConnPool if err != nil { fmt.Println("数据库连接出错:", err) return } } // 捕获异常 func catchException(c *gin.Context) { err := recover() if err != nil { showError(c, fmt.Sprint(err)) } } func GormGetUserList(c *gin.Context) { defer func() { catchException(c) }() name := c.Query("name") myUser := make([]user, 10) tx := gormDB.Where("name=?", name).Find(&myUser).Limit(10) //查询到的有可能为多行,所以采用结构体切片 if tx.Error != nil { showError(c, fmt.Sprint(tx.Error)) return } showSuccess(c, myUser) } func GormGetUserInfo(c *gin.Context) { defer func() { catchException(c) }() id := c.Query("id") myUser := user{} tx := gormDB.Where("id=?", id).First(&myUser) if tx.Error != nil { showError(c, fmt.Sprint(tx.Error)) return } showSuccess(c, myUser) } func GormInsertData(c *gin.Context) { /* //请求参数 { "user_no":1001, "name":"张三", "age":18, "address":"北京昌平" } */ defer func() { catchException(c) }() var myUser user err := c.Bind(&myUser) if err != nil { showError(c, fmt.Sprint(err)) } fmt.Println("myUser", myUser) tx := gormDB.Create(&myUser) fmt.Println(tx) if tx.RowsAffected > 0 { showSuccess(c, tx.RowsAffected) return } else { fmt.Printf("insert failed, err:%v\n", err) showError(c, fmt.Sprint(tx.Error)) } } func GormUpdateData(c *gin.Context) { /* //请求参数 { "id":1, "age":13, "address":"河北" } */ defer func() { catchException(c) }() var myUser user err := c.Bind(&myUser) if err != nil { showError(c, fmt.Sprint(err)) } fmt.Println("myUser", myUser) //先查找 var count int64 gormDB.Model(&user{}).Where("id=?", myUser.Id).Count(&count) if count == 0 { showError(c, "数据不存在") return } //再更新 tx := gormDB.Model(&user{}).Where("id=?", myUser.Id).Updates(&myUser) fmt.Println(tx) //打印结果 if tx.RowsAffected > 0 { showSuccess(c, tx.RowsAffected) } else { showError(c, fmt.Sprint(tx.Error)) } } func GormDeleteData(c *gin.Context) { defer func() { catchException(c) }() id := c.Query("id") //先查找 var count int64 gormDB.Model(&user{}).Where("id=?", id).Count(&count) if count == 0 { showError(c, "数据不存在") return } //再删除 tx := gormDB.Where("id=?", id).Delete(&user{}) fmt.Println(tx) //打印结果 if tx.RowsAffected > 0 { showSuccess(c, tx.RowsAffected) } else { showError(c, fmt.Sprint(tx.Error)) } }
GORM和XORM都是优秀的ORM框架,它们之间的一些区别:
- 查询语言:GORM使用链式查询语法,而XORM使用结构体作为查询条件。XORM的查询语言更为灵活,可以支持更复杂的查询。
- 性能:XORM的性能比GORM更高,在大量数据的情况下,XORM能够更快地进行数据库操作。
- 易用性:GORM的API比XORM更易用,特别是对于没有ORM经验的开发者来说。
- 社区支持:GORM的社区比XORM更大,因此有更多的文档、示例和插件可以使用。
到此这篇关于Go语言Gin框架中使用MySQL数据库的三种方式的文章就介绍到这了,更多相关Gin框架使用MySQL数据库内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!