一、使用xorm

  • 1、如果我们在实际项目中直接写原生sql是没错的,但是对于不太熟悉sql的童鞋来说是比较痛苦的,且代码量比较大,还要避免sql的烦恼,因为我们一般会采用开发框架对应的orm来操作数据库,在gin中比较优秀的orm框架有xormgorm,本小节先介绍xorm的基本使用,xorm支持双向映射,可以将结构体同步到数据库表操作

  • 2、xorm官网地址

    go get github.com/go-xorm/xorm
    
  • 3、封装一个连接数据库的方法

    package utils
    
    import (
    	"fmt"
    	_ "github.com/go-sql-driver/mysql"
    	"github.com/go-xorm/xorm"
    )
    
    var XormDb *xorm.Engine
    
    func init() {
    	fmt.Println("db中的init")
    	// 1.连接数据库
    	sqlStr := "root:123456@tcp(127.0.0.1:3306)/beego?charset=utf8&parseTime=true&loc=Local"
    	var err error
    	XormDb, err = xorm.NewEngine("mysql", sqlStr)
    	if err != nil {
    		fmt.Println("连接数据库失败", err)
    		return
    	}
      // 会在控制台打印执行的sql
      XormDb.ShowSQL(true)
    }
    

二、在gin中操作数据库

  • 1、创建与数据库对应的实体结构体,更多的语法请参考官网来写

    // 定义一个结构体(xorm支持双向映射),没有表的时候会创建,有表的时候会检查字段是否已经更新
    type Student struct {
    	Id        uint64     `xorm:"pk autoincr" json:"id"`
    	Name      string     `xorm:"unique" json:"name"`
    	Age       uint8      `json:"age"`
    	CreatedAt *time.Time `xorm:"created" json:"created_at"`
    	UpdatedAt *time.Time `xorm:"updated" json:"updated_at"`
    }
    
  • 2、同样的定义返回的数据

    var sqlResponse SqlResponse
    
    // 定义数据的返回结构体
    type SqlResponse struct {
    	Code    int         `json:"code"`
    	Message string      `json:"message"`
    	Data    interface{} `json:"data"`
    }
    
  • 3、在main.go中定义init函数来同步数据表

    func init() {
    	fmt.Println("main中的init")
    	// 同步数据
    	err := utils.XormDb.Sync(new(Student))
    	if err != nil {
    		fmt.Println("数据库同步失败", err)
    	}
    }
    

三、在gin中使用xorm对数据的增删改查

  • 1、添加数据

    ...
    router.POST("/xorm", insertData)
    ...
    
    func insertData(c *gin.Context) {
    	var student Student
    	err := c.BindJSON(&student)
    	if err != nil {
    		fmt.Println("解析数据错误", err)
    		sqlResponse.Code = 1
    		sqlResponse.Message = "传递数据错误"
    		c.JSON(http.StatusOK, sqlResponse)
    		return
    	}
    	affected, err := utils.XormDb.Insert(student)
    	if err != nil || affected <= 0 {
    		fmt.Println("插入数据错误", err)
    		sqlResponse.Code = 1
    		sqlResponse.Message = "插入数据错误"
    		c.JSON(http.StatusOK, sqlResponse)
    		return
    	}
    	sqlResponse.Code = 0
    	sqlResponse.Message = "插入数据成功"
    	c.JSON(http.StatusOK, sqlResponse)
    }
    
  • 2、根据id删除数据

    ...
    router.DELETE("/xorm/:id", deleteById)
    ...
    
    func deleteById(c *gin.Context) {
    	id := c.Param("id")
    	intId, err := strconv.Atoi(id)
    	if err != nil {
    		fmt.Println("传递的参数错误")
    		sqlResponse.Code = 1
    		sqlResponse.Message = "传递的ID不能转换为数字类型"
    		c.JSON(http.StatusOK, sqlResponse)
    	}
    	// 1.先检查数据是否存在
    	exist, err := utils.XormDb.Exist(&Student{
    		Id: uint64(intId),
    	})
    	if err != nil {
    		fmt.Println("检查是否存在错误", err)
    		sqlResponse.Code = 1
    		sqlResponse.Message = "参数错误"
    		c.JSON(http.StatusOK, sqlResponse)
    		return
    	}
    	if !exist {
    		sqlResponse.Code = 1
    		sqlResponse.Message = "当前传递的参数数据库不存在"
    		c.JSON(http.StatusOK, sqlResponse)
    		return
    	}
    	// 删除数据
    	affected, err := utils.XormDb.Where("id=?", intId).Delete(&Student{})
    	if err != nil || affected <= 0 {
    		fmt.Println("删除数据失败")
    		sqlResponse.Code = 1
    		sqlResponse.Message = "删除失败"
    		c.JSON(http.StatusOK, sqlResponse)
    		return
    	}
    	sqlResponse.Message = "删除成功"
    	c.JSON(http.StatusOK, sqlResponse)
    }
    
  • 3、根据id修改数据

    ...
    router.PATCH("/xorm/:id", modifyById)
    ...
    
    func modifyById(c *gin.Context) {
    	id := c.Param("id")
    	var student Student
    	err := c.BindJSON(&student)
    	if err != nil {
    		fmt.Println("解析数据错误")
    		sqlResponse.Code = 1
    		sqlResponse.Message = "解析数据错误"
    		c.JSON(http.StatusOK, sqlResponse)
    		return
    	}
    	// 这里不去校验数据是否存在,直接修改
    	affected, err := utils.XormDb.Where("id=?", id).Update(student)
      // affected, err := utils.XormDb.ID(id).Update(student)
    	if err != nil || affected <= 0 {
    		fmt.Println("更新数据失败", err)
    		sqlResponse.Code = 1
    		sqlResponse.Message = "更新数据失败"
    		c.JSON(http.StatusOK, sqlResponse)
    		return
    	}
    	sqlResponse.Message = "更新成功"
    	c.JSON(http.StatusOK, sqlResponse)
    }
    
  • 4、根据id查询数据单条数据

    ...
    ...
    
    func getById(c *gin.Context) {
    	id := c.Param("id")
    	var student Student
    	result, err := utils.XormDb.Where("id =?", id).Get(&student)
    	if err != nil && result {
    		fmt.Println("查询数据失败")
    		sqlResponse.Code = 1
    		sqlResponse.Message = "查询数据失败"
    		c.JSON(http.StatusOK, sqlResponse)
    		return
    	}
    	fmt.Println(student, "查询数据")
    	sqlResponse.Message = "查询成功"
    	sqlResponse.Data = student
    	fmt.Println(result)
    	c.JSON(http.StatusOK, sqlResponse)
    }
    
  • 5、查询全部的数据

    func getMulData(c *gin.Context) {
    	var student []Student
      // 根据id倒序
    	err := utils.XormDb.OrderBy("-id").Find(&student)
    	if err != nil {
    		fmt.Println("查询错误")
    		sqlResponse.Code = 1
    		sqlResponse.Message = "查询失败"
    		c.JSON(http.StatusOK, sqlResponse)
    		return
    	}
    	sqlResponse.Message = "查询成功"
    	sqlResponse.Data = student
    	c.JSON(http.StatusOK, sqlResponse)
    }
    

四、参考文档