• 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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    原生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)))
    }
    
    • 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
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99

    在这里插入图片描述

    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)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述

    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)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    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)))
    }
    
    • 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

    在这里插入图片描述

    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)))
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述

    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)))
    }
    
    • 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
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155

    GORM

    GORM是Go语言中最受欢迎的ORM框架之一。它具有易于使用的API和灵活的查询语言,支持多种类型的数据库,包括MySQL、PostgreSQL、SQLite和SQL Server。GORM还提供了自动迁移功能,可以在应用程序启动时自动创建数据库表和字段。
    使用方法:添加依赖 go get gorm.io/gormgo 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))
    	}
    }
    
    • 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
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164

    GORM和XORM都是优秀的ORM框架,它们之间的一些区别:

    • 查询语言:GORM使用链式查询语法,而XORM使用结构体作为查询条件。XORM的查询语言更为灵活,可以支持更复杂的查询。
    • 性能:XORM的性能比GORM更高,在大量数据的情况下,XORM能够更快地进行数据库操作。
    • 易用性:GORM的API比XORM更易用,特别是对于没有ORM经验的开发者来说。
    • 社区支持:GORM的社区比XORM更大,因此有更多的文档、示例和插件可以使用。

    源代码:https://gitee.com/rxbook/gin-demo/tree/master/dbUtil

  • 相关阅读:
    C#:实现折半插入排序算法(附完整源码)
    asp.net core之配置
    SpringBoot漏洞大全
    FPGA NVMe SSD SQ
    【MySQL--->用户管理】
    自定义MVC
    C++ STL 之顺序存储结构 vector,list,deque异同
    【牛客网面试必刷TOP101】二叉树篇(二)
    HCNP Routing&Switching之端口安全
    Springboot+Redis执行lua脚本
  • 原文地址:https://blog.csdn.net/rxbook/article/details/132318225