gin框架中使用原生sql来操作数据库

一、在gin中使用mysql操作数据库

  • 1、文档地址

    前提是你对sql语句比较熟悉的,不然一般不会选择原生sql方式来操作数据库且代码量比较大

  • 2、安装依赖包

    go get -u github.com/go-sql-driver/mysql
    
  • 3、将mysql连接的单独封装起来

    这里采用init函数来封装,因为init函数会在main函数之前执行的

    // utils/db.go文件
    package utils
    
    import (
    	"database/sql"
    	"fmt"
      // 这个不加在编译的时候不会报错,但是在运行的时候就会报错,因为在编译的时候不需要用所以前面加_
    	_ "github.com/go-sql-driver/mysql"
    )
    
    var SqlDb *sql.DB
    
    func init() {
    	// 1.打开数据库
    	sqlStr := "root:123456@tcp(127.0.0.1:3306)/beego?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
    	}
    }
    
  • 4、先到数据库中创建对应的数据表

      CREATE TABLE `user` (
        `id` int(11) NOT NULL AUTO_INCREMENT primary key COMMENT '主键id',
        `username` varchar(20) NOT NULL unique comment '用户名',
        `password` varchar(100) not null comment '用户密码',
        `avatar` varchar(100)  default null comment '用户头像',
        `status` tinyint(4) default 1 comment '状态',
        `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
        `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表';
    
    
  • 5、在mian.go中定义与数据库表结构一致的结构体

    // 定义提交的数据结构体
    type User struct {
    	UserName string `json:"username"`
    	Password string `json:"password"`
    	Avatar   string `json:"avatar"`
    	Status   uint8  `json:"status"`
    }
    
  • 6、定义要返回的数据的结构体

    var sqlResponse SqlResponse
    
    // 定义数据的返回结构体
    type SqlResponse struct {
    	Code    int         `json:"code"`
    	Message string      `json:"message"`
    	Data    interface{} `json:"data"`
    }
    

二、在gin框架中对数据的增删改查操作

  • 1、添加数据

    func main() {
    	router := gin.Default()
    	router.POST("/sql", insertData)
    	router.Run(":9000")
    }
    
    // 添加数据的方法
    func insertData(c *gin.Context) {
    	var user User
    	err := c.Bind(&user)
    	if err != nil {
    		sqlResponse.Code = 1
    		sqlResponse.Message = "参数错误"
    		c.JSON(http.StatusOK, sqlResponse)
    		return
    	}
    	sqlStr := "insert into user(username, password, avatar, status) values(?,?,?,?)"
    	res, err := utils.SqlDb.Exec(sqlStr, user.UserName, user.Password, user.Avatar, user.Status)
    	if err != nil {
    		fmt.Println("插入数据错误", err)
    		sqlResponse.Code = 1
    		sqlResponse.Message = "插入数据错误"
    		c.JSON(http.StatusOK, sqlResponse)
    		return
    	}
    	sqlResponse.Code = 0
    	sqlResponse.Message = "插入数据成功"
    	sqlResponse.Data = "成功"
    	c.JSON(http.StatusOK, sqlResponse)
    	fmt.Println(res.RowsAffected())
    }
    
  • 2、根据id删除数据

    ...
    router.DELETE("sql/:id", deleteById)
    ...
    
    // 根据id删除数据
    func deleteById(c *gin.Context) {
    	id := c.Param("id")
    	sqlStr := "delete from user where id = ?"
    	res, err := utils.SqlDb.Exec(sqlStr, id)
    	if err != nil {
    		sqlResponse.Code = 1
    		sqlResponse.Message = "删除失败"
    		c.JSON(http.StatusOK, sqlResponse)
    		fmt.Println("删除失败", err)
    		return
    	}
    	sqlResponse.Code = 0
    	sqlResponse.Message = "删除成功"
    	c.JSON(http.StatusOK, sqlResponse)
    	fmt.Println(res.RowsAffected())
    }
    
  • 3、根据id修改数据

    ...
    router.PATCH("sql/:id", modifyById)
    ...
    
    //根据id修改数据
    func modifyById(c *gin.Context) {
    	id := c.Param("id")
    	var user User
    	err := c.Bind(&user)
    	if err != nil {
    		sqlResponse.Code = 1
    		sqlResponse.Message = "接受参数错误"
    		c.JSON(http.StatusOK, sqlResponse)
    		return
    	}
    	sqlStr := "update user set status = ? where id = ?"
    	result, err := utils.SqlDb.Exec(sqlStr, user.Status, id)
    	if err != nil {
    		sqlResponse.Code = 1
    		sqlResponse.Message = "更新错误"
    		c.JSON(http.StatusOK, sqlResponse)
    		return
    	}
    	fmt.Println(result.RowsAffected())
    	sqlResponse.Code = 0
    	sqlResponse.Message = "更新成功"
    	c.JSON(http.StatusOK, sqlResponse)
    }
    
  • 4、根据id查询一条数据

    ...
    router.GET("sql/:id", findById)
    ...
    
    //根据id查询数据
    func findById(c *gin.Context) {
    	id := c.Param("id")
    	sqlStr := "select username, avatar, status from user where id = ?"
    	// 定义一个接收的数据
    	var user User
      // 注意点,这里上面select上定义几个字段,这里Scan就要有几个接收
    	err := utils.SqlDb.QueryRow(sqlStr, id).Scan(&user.UserName, &user.Avatar, &user.Status)
    	if err != nil {
    		fmt.Println(err)
    		sqlResponse.Code = 1
    		sqlResponse.Message = "查询失败"
    		c.JSON(http.StatusOK, sqlResponse)
    		return
    	}
    	sqlResponse.Code = 0
    	sqlResponse.Message = "查询成功"
    	sqlResponse.Data = user
    	c.JSON(http.StatusOK, sqlResponse)
    }
    
    ...
    // 处理下不需要返回密码为空的字段
    sqlResponse.Code = 0
    sqlResponse.Message = "查询成功"
    // 这不需要返回密码字段,特别包装下
    sqlResponse.Data = map[string]interface{}{
      "username": user.UserName,
      "avatar":   user.Avatar,
      "status":   user.Status,
    }
    c.JSON(http.StatusOK, sqlResponse)
    ...
    
  • 5、查询多条数据

    ...
    router.GET("sql", findMulData)
    ...
    //查询多条数据
    func findMulData(c *gin.Context) {
    	sqlStr := "select username, avatar, status from user"
    	rows, err := utils.SqlDb.Query(sqlStr)
    	if err != nil {
    		fmt.Println("查询错误")
    		sqlResponse.Code = 1
    		sqlResponse.Message = "查询失败"
    		c.JSON(http.StatusOK, sqlResponse)
    		return
    	}
    	defer rows.Close()
    	// 创建一个切片来存储数据
    	resultUser := make([]User, 0)
    	for rows.Next() {
    		var user User
    		rows.Scan(&user.UserName, &user.Avatar, &user.Status)
    		// 追加到切片中
    		resultUser = append(resultUser, user)
    	}
    	sqlResponse.Message = "查询成功"
    	sqlResponse.Data = resultUser
    	c.JSON(http.StatusOK, sqlResponse)
    }
    

你可能感兴趣的:(go)