数据库是业务应用的核心,本节主要讲解gin框架(Go语言)操作原生数据库、go语言数据库ORM框架(gorm和xorm)。

1、原生数据库

package main

import (
	"database/sql"
	"fmt"
	"github.com/gin-gonic/gin"
	_ "github.com/go-sql-driver/mysql"
	"net/http"
)

var sqlDb *sql.DB           //数据库连接db
var sqlResponse SqlResponse //响应client的数据
func init() {
	//1、打开数据库
	//parseTime:时间格式转换(查询结果为时间时,是否自动解析为时间);
	// loc=Local:MySQL的时区设置
	sqlStr := "root:123456@tcp(127.0.0.1:3306)/testdb?charset=utf8&parseTime=true&loc=Local"
	var err error
	sqlDb, err = sql.Open("mysql", sqlStr)
	if err != nil {
		fmt.Println("数据库打开出现了问题:", err)
		return
	}
	//2、 测试与数据库建立的连接(校验连接是否正确)
	err = sqlDb.Ping()
	if err != nil {
		fmt.Println("数据库连接出现了问题:", err)
		return
	}
}

//Client提交的数据
type SqlUser struct {
	Name    string `json:"name"`
	Age     int    `json:"age"`
	Address string `json:"address"`
}

//应答体(响应client的请求)
type SqlResponse struct {
	Code    int         `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data"`
}

func main() {
	r := gin.Default()
	//数据库的CRUD--->gin的 post、get、put、delete方法
	r.POST("sql/insert", insertData) //添加数据
	r.GET("sql/get",getData) //查询数据(单条记录)
	r.GET("sql/mulget",getMulData)//查询数据(多条记录)
	r.PUT("sql/update",updateData)//更新数据
	r.DELETE("sql/delete",deleteData)//删除数据
	r.Run(":9090")
}

func deleteData(c *gin.Context) {
	name:=c.Query("name")
	var count int
	//1、先查询
	sqlStr:="select count(*) from user where name=?"
	err := sqlDb.QueryRow(sqlStr, name).Scan(&count)
	if  count<=0||err!=nil{
		sqlResponse.Code = http.StatusBadRequest
		sqlResponse.Message = "删除的数据不存在"
		sqlResponse.Data = "error"
		c.JSON(http.StatusOK, sqlResponse)
		return
	}
	//2、再删除
	delStr:="delete from user where name=?"
	ret, err := sqlDb.Exec(delStr, name)
	if err != nil {
		fmt.Printf("delete failed, err:%v\n", err)
		sqlResponse.Code = http.StatusBadRequest
		sqlResponse.Message = "删除失败"
		sqlResponse.Data = "error"
		c.JSON(http.StatusOK, sqlResponse)
		return
	}
	sqlResponse.Code = http.StatusOK
	sqlResponse.Message = "删除成功"
	sqlResponse.Data = "OK"
	c.JSON(http.StatusOK, sqlResponse)
	fmt.Println(ret.LastInsertId()) //打印结果
}

func updateData(c *gin.Context) {
	var u SqlUser
	err := c.Bind(&u)
	if err != nil {
		sqlResponse.Code = http.StatusBadRequest
		sqlResponse.Message = "参数错误"
		sqlResponse.Data = "error"
		c.JSON(http.StatusOK, sqlResponse)
		return
	}
	sqlStr:="update user set age=? ,address=? where name=?"
	ret, err := sqlDb.Exec(sqlStr, u.Age, u.Address, u.Name)
	if err != nil {
		fmt.Printf("update failed, err:%v\n", err)
		sqlResponse.Code = http.StatusBadRequest
		sqlResponse.Message = "更新失败"
		sqlResponse.Data = "error"
		c.JSON(http.StatusOK, sqlResponse)
		return
	}
	sqlResponse.Code = http.StatusOK
	sqlResponse.Message = "更新成功"
	sqlResponse.Data = "OK"
	c.JSON(http.StatusOK, sqlResponse)
	fmt.Println(ret.LastInsertId()) //打印结果
}

func getMulData(c *gin.Context) {
	address:=c.Query("address")
	sqlStr:="select name,age from user where address=?"
	rows, err := sqlDb.Query(sqlStr, address)
	if err!=nil {
		sqlResponse.Code = http.StatusBadRequest
		sqlResponse.Message = "查询错误"
		sqlResponse.Data = "error"
		c.JSON(http.StatusOK, sqlResponse)
		return
	}
	defer rows.Close()
	resUser:=make([]SqlUser,0)
	for rows.Next(){
		var userTemp SqlUser
		rows.Scan(&userTemp.Name,&userTemp.Age)
		userTemp.Address=address
		resUser=append(resUser,userTemp)
	}
	sqlResponse.Code = http.StatusOK
	sqlResponse.Message = "读取成功"
	sqlResponse.Data=resUser
	c.JSON(http.StatusOK, sqlResponse)
}

func getData(c *gin.Context) {
	name:=c.Query("name")
	sqlStr:="select age,address from user where name=?"
	var u SqlUser
	err := sqlDb.QueryRow(sqlStr, name).Scan(&u.Age, &u.Address)
	if err!=nil {
		sqlResponse.Code = http.StatusBadRequest
		sqlResponse.Message = "查询错误"
		sqlResponse.Data = "error"
		c.JSON(http.StatusOK, sqlResponse)
		return
	}
	u.Name=name
	sqlResponse.Code = http.StatusOK
	sqlResponse.Message = "读取成功"
	sqlResponse.Data = u
	c.JSON(http.StatusOK, sqlResponse)
}

func insertData(c *gin.Context) {
	var u SqlUser
	err := c.Bind(&u)
	if err != nil {
		sqlResponse.Code = http.StatusBadRequest
		sqlResponse.Message = "参数错误"
		sqlResponse.Data = "error"
		c.JSON(http.StatusOK, sqlResponse)
		return
	}
	sqlStr := "insert into user(name, age, address) values (?,?,?)"
	ret, err := sqlDb.Exec(sqlStr, u.Name, u.Age, u.Address)
	if err != nil {
		fmt.Printf("insert failed, err:%v\n", err)
		sqlResponse.Code = http.StatusBadRequest
		sqlResponse.Message = "写入失败"
		sqlResponse.Data = "error"
		c.JSON(http.StatusOK, sqlResponse)
		return
	}
	sqlResponse.Code = http.StatusOK
	sqlResponse.Message = "写入成功"
	sqlResponse.Data = "OK"
	c.JSON(http.StatusOK, sqlResponse)
	fmt.Println(ret.LastInsertId()) //打印结果

}

//todo:  go-sql-driver地址:https://github.com/go-sql-driver/mysql

特别留意:数据库驱动的包(_ "github.com/go-sql-driver/mysql")不要忘了,不然程序会报错。

2、xorm

xorm是一个简单而强大的Go语言ORM库,通过它可以使数据库操作非常简便。

核心代码如下:

var x *xorm.Engine
var xormResponse XormResponse

//定义结构体(xorm支持双向映射);没有表,会进行创建
type Stu struct {
	Id      int64     `xorm:"pk autoincr" json:"id"` //指定主键并自增
	StuNum  string    `xorm:"unique" json:"stu_num"`
	Name    string    `json:"name"`
	Age     int       `json:"age"`
	Created time.Time `xorm:"created" json:"created"`
	Updated time.Time `xorm:"updated" json:"updated"`
}

//应答体
type XormResponse struct {
	Code    int         `json:"code"`
	Message string      `json:"msg"`
	Data    interface{} `json:"data"`
}

func init() {
	sqlStr := "root:123456@tcp(127.0.0.1:3306)/xorm?charset=utf8&parseTime=true&loc=Local" //xorm代表数据库名称
	var err error
	x, err = xorm.NewEngine("mysql", sqlStr) //1、创建数据库引擎
	if err != nil {
		fmt.Println("数据库连接失败:", err)
	}
	//2、创建或者同步表(名称为Stu)
	err = x.Sync(new(Stu))
	if err != nil {
		fmt.Println("数据表同步失败:", err)
	}
}
func main() {
	r := gin.Default()
	//数据库的CRUD--->gin的 post、get、put、delete方法
	r.POST("xorm/insert", xormInsetData)    //添加数据
	r.GET("xorm/get", xormGetData)          //查询数据(单条记录)
	r.GET("xorm/mulget", xormGetMulData)    //查询数据(多条记录)
	r.PUT("xorm/update", xormUpdateData)    //更新数据
	r.DELETE("xorm/delete", xormDeleteData) //删除数据
	r.Run(":9090")
}

func xormGetData(c *gin.Context) {
	stuNum := c.Query("stu_num")
	var stus []Stu
	err := x.Where("stu_num=?", stuNum).Find(&stus)
	if err != nil {
		xormResponse.Code = http.StatusBadRequest
		xormResponse.Message = "查询错误"
		xormResponse.Data = "error"
		c.JSON(http.StatusOK, xormResponse)
		return
	}
	xormResponse.Code = http.StatusOK
	xormResponse.Message = "读取成功"
	xormResponse.Data = stus
	c.JSON(http.StatusOK, xormResponse)
}

func xormInsetData(c *gin.Context) {
	var s Stu
	err := c.Bind(&s)
	if err != nil {
		xormResponse.Code = http.StatusBadRequest
		xormResponse.Message = "参数错误"
		xormResponse.Data = "error"
		c.JSON(http.StatusOK, xormResponse)
		return
	}
	affected, err := x.Insert(s)
	if err != nil || affected <= 0 {
		fmt.Printf("insert failed, err:%v\n", err)
		xormResponse.Code = http.StatusBadRequest
		xormResponse.Message = "写入失败"
		xormResponse.Data = err
		c.JSON(http.StatusOK, xormResponse)
		return
	}
	xormResponse.Code = http.StatusOK
	xormResponse.Message = "写入成功"
	xormResponse.Data = "OK"
	c.JSON(http.StatusOK, xormResponse)
	fmt.Println(affected) //打印结果

}

//TODO: xom文档地址:https://github.com/go-xorm/xorm

鉴于篇幅限制,详细内容在文章末尾对应的视频中有讲解,在此略过。

3、gorm

特别注意:gorm原来的版本已经废弃,新版本进行了迁移,地址:https://gorm.io/。新版本与旧版本有很大的区别,本节主要讲解新版本。

核心代码如下:

//特别注意:结构体名称为:Product,创建的表的名称为:Products
type Product struct {
	ID             int       `gorm:"primaryKey;autoIncrement" json:"id"`
	Number         string    `gorm:"unique" json:"number"`                       //商品编号(唯一)
	Category       string    `gorm:"type:varchar(256);not null" json:"category"` //商品类别
	Name           string    `gorm:"type:varchar(20);not null" json:"name"`      //商品名称
	MadeIn         string    `gorm:"type:varchar(128);not null" json:"made_in"`  //生产地
	ProductionTime time.Time `json:"production_time"`                            //生产时间
}

//应答体
type GormResponse struct {
	Code    int         `json:"code"`
	Message string      `json:"msg"`
	Data    interface{} `json:"data"`
}

var gormDB *gorm.DB
var gormResponse GormResponse

func init() {
	var err error
	sqlStr := "root:123456@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=true&loc=Local"
	gormDB, err = gorm.Open(mysql.Open(sqlStr), &gorm.Config{}) //配置项中预设了连接池 ConnPool
	if err != nil {
		fmt.Println("数据库连接出现了问题:", err)
		return
	}

}

func main() {
	r := gin.Default()
	//数据库的CRUD--->gin的 post、get、put、delete方法
	r.POST("gorm/insert", gormInsertData)   //添加数据
	r.GET("gorm/get", gormGetData)          //查询数据(单条记录)
	r.GET("gorm/mulget", gormGetMulData)    //查询数据(多条记录)
	r.PUT("gorm/update", gormUpdateData)    //更新数据
	r.DELETE("gorm/delete", gormDeleteData) //删除数据
	r.Run(":9090")
}
func gormGetData(c *gin.Context) {
	//=============捕获异常============
	defer func() {
		err := recover()
		if err != nil {
			gormResponse.Code = http.StatusBadRequest
			gormResponse.Message = "错误"
			gormResponse.Data = err
			c.JSON(http.StatusBadRequest, gormResponse)
		}
	}()
	//============
	number := c.Query("number")
	product := Product{}
	tx := gormDB.Where("number=?", number).First(&product)
	if tx.Error != nil {
		gormResponse.Code = http.StatusBadRequest
		gormResponse.Message = "查询错误"
		gormResponse.Data = tx.Error
		c.JSON(http.StatusOK, gormResponse)
		return
	}
	gormResponse.Code = http.StatusOK
	gormResponse.Message = "读取成功"
	gormResponse.Data = product
	c.JSON(http.StatusOK, gormResponse)
}

func gormInsertData(c *gin.Context) {
	//=============捕获异常============
	defer func() {
		err := recover()
		if err != nil {
			gormResponse.Code = http.StatusBadRequest
			gormResponse.Message = "错误"
			gormResponse.Data = err
			c.JSON(http.StatusBadRequest, gormResponse)
		}
	}()
	//============
	var p Product
	err := c.Bind(&p)
	if err != nil {
		gormResponse.Code = http.StatusBadRequest
		gormResponse.Message = "参数错误"
		gormResponse.Data = err
		c.JSON(http.StatusOK, gormResponse)
		return
	}
	fmt.Println(p)
	tx := gormDB.Create(&p)
	if tx.RowsAffected > 0 {
		gormResponse.Code = http.StatusOK
		gormResponse.Message = "写入成功"
		gormResponse.Data = "OK"
		c.JSON(http.StatusOK, gormResponse)
		return
	}
	fmt.Printf("insert failed, err:%v\n", err)
	gormResponse.Code = http.StatusBadRequest
	gormResponse.Message = "写入失败"
	gormResponse.Data = tx
	c.JSON(http.StatusOK, gormResponse)
	fmt.Println(tx) //打印结果
}

//Todo:GitHub地址:https://github.com/go-gorm/gorm
//文档地址:https://gorm.io/

鉴于篇幅限制,详细内容在文章末尾对应的视频中有讲解,在此略过。