Skip to content

数据库

Quote

对于Gin本身,并没有对数据库的操作,本文实现的是,通过http访问程序,然后操作mysql数据库库。

查询

  1. mysql DDL
    SET NAMES utf8mb4;
    SET FOREIGN_KEY_CHECKS = 0;
    
    -- ----------------------------
    -- Table structure for user
    -- ----------------------------
    DROP TABLE IF EXISTS `user`;
    CREATE TABLE `user` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `name` varchar(32) NOT NULL DEFAULT '' COMMENT '用户名',
    `pwd` varchar(32) NOT NULL DEFAULT '' COMMENT '密码',
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
    
    -- ----------------------------
    -- Records of user
    -- ----------------------------
    BEGIN;
    INSERT INTO `user` VALUES (1, 'zhangsan', 'admin123');
    INSERT INTO `user` VALUES (2, 'lisi', 'admin123');
    COMMIT;
    
    SET FOREIGN_KEY_CHECKS = 1;
    
  2. 接下来,我们就查询这张表,并将查询的结果以json的形式,返回给客户端。
    package main
    
    import (
        "database/sql"
        "fmt"
        "github.com/gin-gonic/gin"
        "log"
        "net/http"
    )
    
    // 定义User类型结构
    type User struct {
        Id   int    `json:"id"`
        User string `json:"user"`
        Pwd  string `json:"pwd"`
    }
    
    func main() {
        r := gin.Default()
        //get方法的查询
        r.GET("/user", func(c *gin.Context) {
            users, err := getAll()
            if err != nil {
                log.Fatal(err)
            }
            //H is a shortcut for map[string]interface{}
            c.JSON(http.StatusOK, gin.H{
                "result": users,
                "count":  len(users),
            })
        })
        r.Run(":80")
    }
    
    // 定义一个getALL函数用于查询所有的数据
    func getAll() (users []User, err error) {
    
        // 连接数据库
        db, _ := sql.Open("mysql", "root:root@tcp(localhost:3306)/jartin?charset=utf8")
        // 错误检查
        if err != nil {
            fmt.Println("连接错误信息: ", err.Error())
            log.Fatal(err.Error())
        }
        // 推迟数据库连接的关闭
        defer db.Close()
    
        // 查询
        rows, err := db.Query("SELECT * FROM user")
        if err != nil {
            fmt.Println("查询错误信息: ", err.Error())
            log.Fatal(err.Error())
        }
    
        for rows.Next() {
            var user User
            // 遍历表中所有行的信息
            rows.Scan(&user.Id, &user.User, &user.Pwd)
            // 将user添加到users中
            users = append(users, user)
        }
        // 最后关闭连接
        defer rows.Close()
        return
    }
    
  3. 访问结果
    curl localhost/user
    
    {
        "count": 2
        "reuslt": [
            {
                "id": "1",
                "user": "zhangsan",
                "pwd": "admin123",
            },
            {
                "id": "2",
                "user": "lisi",
                "pwd": "admin123",
            },
        ]
    }
    

插入

  1. 我们可以设计一个方法用于向数据库中添加数据:
    //插入数据
    func add(user User) (Id int, err error) {
    
        //1.操作数据库
        db, _ := sql.Open("mysql", "root:hanru1314@tcp(127.0.0.1:3306)/mytest?charset=utf8")
        //错误检查
        if err != nil {
            log.Fatal(err.Error())
        }
        //推迟数据库连接的关闭
        defer db.Close()
        stmt, err := db.Prepare("INSERT INTO user_info(username, password) VALUES (?, ?)")
        if err != nil {
            return
        }
        //执行插入操作
        rs, err := stmt.Exec(user.Username, user.Password)
        if err != nil {
            return
        }
        //返回插入的id
        id, err := rs.LastInsertId()
        if err != nil {
            log.Fatalln(err)
        }
        //将id类型转换
        Id = int(id)
        defer stmt.Close()
        return
    }
    
  2. 然后我们添加一个POST的路由,当通过post请求的时候,我们向数据库中插入数据:
    //利用post方法新增数据
    router.POST("/add", func(c *gin.Context) {
        var  u User
        err := c.Bind(&u)
        if err != nil {
            log.Fatal(err)
        }
        Id, err := add(u)
        fmt.Print("id=", Id)
        c.JSON(http.StatusOK, gin.H{
            "message": fmt.Sprintf("%s 插入成功", u.Username),
        })
    })
    
  3. 因为我们需要绑定struct类型,所以还需要修改之前的User:
    //定义User类型结构
    type User struct {
        Id       int    `json:"id" form:"id"`
        Username string `json:"username" form:"username"`
        Password string `json:"password" form:"password"`
    }
    

修改

  1. 添加一个update方法用于修改数据,我们实现的是根据id修改其他的字段:
    //修改数据
    func update(user User) (rowsAffected int64, err error) {
    
        //1.操作数据库
        db, _ := sql.Open("mysql", "root:hanru1314@tcp(127.0.0.1:3306)/mytest?charset=utf8")
        //错误检查
        if err != nil {
            log.Fatal(err.Error())
        }
        //推迟数据库连接的关闭
        defer db.Close()
        stmt, err := db.Prepare("UPDATE  user_info SET username=?, password=? WHERE id=?")
        if err != nil {
            return
        }
        //执行修改操作
        rs, err := stmt.Exec(user.Username, user.Password,user.Id)
        if err != nil {
            return
        }
        //返回插入的id
        rowsAffected,err =rs.RowsAffected()
        if err != nil {
            log.Fatalln(err)
        }
        defer stmt.Close()
        return
    }
    
  2. 然后在main中新添加一个路由:
    //利用put方法修改数据
    router.PUT("/update", func(c *gin.Context) {
        var  u User
        err := c.Bind(&u)
        if err != nil {
            log.Fatal(err)
        }
        num, err := update(u)
        fmt.Print("num=", num)
        c.JSON(http.StatusOK, gin.H{
            "message": fmt.Sprintf("修改id: %d 成功", u.Id),
        })
    })
    

删除

  1. 我们可以根据Id删除一条数据,删除刚刚修改的id为10的数据,先添加一个delete方法:

    //通过id删除
    func del(id int) (rows int, err error) {
        //1.操作数据库
        db, _ := sql.Open("mysql", "root:hanru1314@tcp(127.0.0.1:3306)/mytest?charset=utf8")
        //错误检查
        if err != nil {
            log.Fatal(err.Error())
        }
        //推迟数据库连接的关闭
        defer db.Close()
        stmt, err := db.Prepare("DELETE FROM user_info WHERE id=?")
        if err != nil {
            log.Fatalln(err)
        }
    
        rs, err := stmt.Exec(id)
        if err != nil {
            log.Fatalln(err)
        }
        //删除的行数
        row, err := rs.RowsAffected()
        if err != nil {
            log.Fatalln(err)
        }
        defer stmt.Close()
        rows = int(row)
        return
    }
    

  2. 然后再main中注册一个路由:

    //利用DELETE请求方法通过id删除
    router.DELETE("/delete/:id", func(c *gin.Context) {
        id := c.Param("id")
    
        Id, err := strconv.Atoi(id)
    
        if err != nil {
            log.Fatalln(err)
        }
        rows, err := del(Id)
        if err != nil {
            log.Fatalln(err)
        }
        fmt.Println("delete rows ", rows)
    
        c.JSON(http.StatusOK, gin.H{
            "message": fmt.Sprintf("Successfully deleted user: %s", id),
        })
    })