33

半小时快速入门golang完成简单的web用户管理

 4 years ago
source link: https://www.tuicool.com/articles/m2uYbeQ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一.课程目标

  • 本课程目标是让新手能够在最短的时间内了解到golang的增删改查流程. 从而让入门web开发更加容易.
  • 本实例是快速实现一个用户的增删改查, 采用前后端分离模式, 后端采用 gorose orm + gin框架 完成api的开发, 前端使用 原生html+css+jquery+ajax 交互数据.
  • 本项目源码已经发布到github: https://github.com/gohouse/go...

二.安装基础环境和依赖库

# 安装golang
yum -y install golang

# 安装gin web框架
go get https://github.com/gin-gonic/gin

# 安装gorose orm框架
go get https://github.com/gohouse/gorose

# 安装sqlite3驱动
go get https://github.com/mattn/go-sqlite3

注: 这里只是做一个centos下的命令行示例, 其他操作系统类似, 只是需要把上边几个依赖安装好即可.实际使用中,建议使用vgo管理.

三.创建文件并开启简单的http服务

1.创建文件

cd $GOPATH/src/
mkdir gopro && cd gopro
touch main.go

2.编辑 main.go ,内容如下

package main

import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.String(200, "欢迎来到golang入门用户管理api服务系统")
    })
    
    // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080" )
    r.Run()
}

运行结果如下:

$ go run main.go 
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:    export GIN_MODE=release
 - using code:    gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /                         --> main.BootGin.func1 (3 handlers)
[GIN-debug] GET    /UserAdd                  --> main.UserAdd (4 handlers)
[GIN-debug] GET    /UserList                 --> main.UserList (4 handlers)
[GIN-debug] GET    /UserEdit                 --> main.UserEdit (4 handlers)
[GIN-debug] GET    /UserDelete               --> main.UserDelete (4 handlers)
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080

浏览器访问 http://localhost :8080 即可看到欢迎语了,一个基本的http服务已经搭建完毕

四.开发接口

初始化gorose orm

使用单例封装一个 gorose 初始驱动函数,这里采用 sqlite3 作为示例的数据库, 实际使用跟 mysql 一致

var once sync.Once
var engin *gorose.Engin

//BootGorose 初始化gorose, 单例模式
func BootGorose() {
    var err error
    once.Do(func() {
        engin, err = gorose.Open(&gorose.Config{
            Driver: "sqlite3",
            Dsn:    "db2.sqlite",
        })
        if err != nil {
            panic(err.Error())
        }
    })
}

封装一个 DB() 函数方便快捷调用

// DB orm快捷使用函数
func DB() gorose.IOrm {
    return engin.NewOrm()
}

初始化用户表

该表作为示例的增删改查对象

// UserInit 初始化用户表
// 实际使用中,建议不要放到代码中,避免每一次都会执行
func UserInit() {
    dbSql := `CREATE TABLE IF NOT EXISTS "users" (
     "uid" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
     "username" TEXT NOT NULL default "",
     "age" integer NOT NULL default 0
)`
    affected_rows, err := DB().Execute(dbSql)
    if err != nil {
        panic(err.Error())
    }
    if affected_rows == 0 {
        return
    }
}

增加用户

1.添加路由

...
router.GET("/UserAdd", UserAdd)
...

2.编写 UserAdd 方法

func UserAdd(c *gin.Context) {
    username := c.Query("username")
    age := c.DefaultQuery("age", "0")

    var data = make(map[string]interface{})
    if username == "" {
        c.JSON(http.StatusOK, FailReturn("用户名不能为空"))
        return
    }
    data["username"] = username
    if age != "0" {
        data["age"] = age
    }
    affected_rows, err := DB().Table("users").Data(data).Insert()
    if err != nil {
        c.JSON(http.StatusOK, FailReturn(err.Error()))
        return
    }
    c.JSON(http.StatusOK, SuccessReturn(affected_rows))
}

这里新增了两个工具函数 SuccessReturn()FailReturn() ,方便api统一返回使用,具体方法如下:

// SuccessReturn api正确返回函数
func SuccessReturn(msg interface{}) map[string]interface{} {
    var res = make(map[string]interface{})
    res["data"] = msg
    res["code"] = http.StatusOK
    res["msg"] = "success"

    return res
}

// FailReturn api错误返回函数
func FailReturn(msg interface{}) map[string]interface{} {
    var res = make(map[string]interface{})
    res["data"] = ""
    res["code"] = http.StatusBadRequest
    res["msg"] = msg

    return res
}

3.我们运行并测试一下效果,浏览器访问: http://localhost :8080/UserAdd?username=fizz .

浏览器显示如下内容, 则表示成功.

{
    "code": 200,
    "data": 1,
    "msg": "success"
}

我们可以继续执行,多添加几条数据,方便测试:

http://localhost :8080/UserAdd?username=fizz2&age=18

等我们完善一下查看接口, 就可以查看刚才添加的数据了

查看用户

1.添加路由

...
router.GET("/UserList", UserList)
...

2.编写 UserList 方法

// UserList 获取用户列表
func UserList(c *gin.Context) {
    // 默认查询10条数据
    userList, err := DB().Table("users").Limit(10).Get()
    if err != nil {
        c.JSON(http.StatusOK, FailReturn(err.Error()))
        return
    }
    c.JSON(http.StatusOK, SuccessReturn(userList))
}

3.我们运行并测试一下效果,浏览器访问: http://localhost :8080/UserList

浏览器显示如下内容, 证明我们刚才添加的数据是正确的

{
    "code": 200,
    "data": [
        {
            "age": 0,
            "uid": 1,
            "username": "fizz"
        },
        {
            "age": 18,
            "uid": 2,
            "username": "fizz2"
        }
    ],
    "msg": "success"
}

修改用户

1.添加路由

...
router.GET("/UserEdit", UserEdit)
...

2.编写 UserEdit 方法

// UserEdit 用户编辑
func UserEdit(c *gin.Context) {
    // 按照主键编辑
    uid := c.Query("uid")
    username := c.DefaultQuery("username", "")
    age := c.DefaultQuery("age", "0")
    if uid == "" {
        c.JSON(http.StatusOK, FailReturn("用户id不能为空"))
        return
    }
    if username == "" && age == "0" {
        c.JSON(http.StatusOK, FailReturn("未修改"))
        return
    }

    var data = make(map[string]interface{})
    if username != "" {
        data["username"] = username
    }
    if age != "0" {
        data["age"] = age
    }
    // 执行入库操作
    affected_rows, err := DB().Table("users").Where("uid", uid).Data(data).Update()
    if err != nil {
        c.JSON(http.StatusOK, FailReturn(err.Error()))
        return
    }
    c.JSON(http.StatusOK, SuccessReturn(affected_rows))
}

3.我们运行并测试一下效果,浏览器访问: http://localhost :8080/UserEdit?username=fizz22&uid=2

浏览器显示如下内容, 证明修改成功

{
    "code": 200,
    "data": [
        {
            "age": 0,
            "uid": 1,
            "username": "fizz"
        },
        {
            "age": 18,
            "uid": 2,
            "username": "fizz22"
        }
    ],
    "msg": "success"
}

删除用户

1.添加路由

...
router.GET("/UserDelete", UserDelete)
...

2.编写 UserDelete 方法

// UserDelete 用户删除
func UserDelete(c *gin.Context) {
    // 按主键删除
    uid := c.Query("uid")
    if uid == "" {
        c.JSON(http.StatusOK, FailReturn("用户id不能为空"))
        return
    }
    affected_rows, err := DB().Table("users").Where("uid", uid).Delete()
    if err != nil {
        c.JSON(http.StatusOK, FailReturn(err.Error()))
        return
    }
    c.JSON(http.StatusOK, SuccessReturn(affected_rows))
}

3.我们运行并测试一下效果,浏览器访问: http://localhost :8080/UserDelete?uid=2

浏览器显示如下内容, 证明删除成功

{
    "code": 200,
    "data": 0,
    "msg": "success"
}

4.最后我们再查看一下数据, http://localhost :8080/UserList

{
    "code": 200,
    "data": [
        {
            "age": 0,
            "uid": 1,
            "username": "fizz"
        }
    ],
    "msg": "success"
}

发现uid=2的数据已经删掉了,到此, 增删改查的api接口全部搞定

完成前端页面

1. 编写html+css

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>golang用户管理示例</title>
    <style>
        #user-box{
            max-width: 600px;
            margin: 0 auto;
        }
        table{
            text-align: center;
            border: 1px solid #000;
        }
        th{
            width: 150px;
        }
    </style>
</head>
<body>
<center><h1>欢迎来到golang入门用户管理api服务系统</h1></center>
<hr>
<div id="user-box">
    <button onclick="UserAdd()">新增</button>
    <table>
        <tr>
            <th>uid</th>
            <th>用户名</th>
            <th>年龄</th>
            <th>操作</th>
        </tr>
    </table>
</div>
</body>
</html>

2. 编写增加和修改的模态框弹层

<div id="modal">
    <!-- 模态框 -->
    <dialog>
        <p>操作</p>
        <hr>
        <input type="hidden" id="uid">
        <p>
            用户名: <br>
            <input type="text" id="username">
        </p>

        <p>
            年  龄: <br>
            <input type="text" id="age">
        </p>

        <button onclick="UserSubmit()">提交</button>
        <button onclick="dialog.hide()">关闭</button>
    </dialog>
</div>

3. 编写JavaScript

<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
    var dialog = $("dialog");
    var uid = $("#uid");
    var username = $("#username");
    var age = $("#age");

    // 初始化数据
    UserList();

    function UserSubmit() {
        var url = "http://localhost:8080/UserEdit";
        var uidVal = uid.val();
        if (uidVal=="") {
            url = "http://localhost:8080/UserAdd"
        }
        $.get(url,{
            uid:uid.val(),
            username:username.val(),
            age:age.val()
        },function (e) {
            console.log(e);
            if (e.code!=200) {
                alert("失败")
            }
            // dialog.hide()
            window.location.reload()
        })
    }
    function UserAdd() {
        dialogInit()
        dialog.show()
    }
    function UserEdit(uidParam,usernameParam,ageParam) {
        dialogInit()
        dialog.show()
        uid.val(uidParam)
        username.val(usernameParam)
        age.val(ageParam)
    }
    function UserDelete(uidParam) {
        var url = "http://localhost:8080/UserDelete"
        $.get(url,{uid,uidParam},function (e) {
            console.log(e);
            dialog.hide()
        })
    }
    function dialogInit() {
        uid.val("")
        username.val("")
        age.val("")
    }
    function UserList() {
        var url = "http://localhost:8080/UserList"
        $.get(url,{},function (e) {
            if (e.code==200) {
                if (e.data.length>0) {
                    for(var i in e.data) {
                        var data = e.data[i]
                        $("table").append("<tr>\n" +
                            "            <td>"+data.uid+"</td>\n" +
                            "            <td>"+data.username+"</td>\n" +
                            "            <td>"+data.age+"</td>\n" +
                            "            <td><a href='javascript:;' onclick='UserEdit("+data.uid+",\""+data.username+"\","+data.age+")'>编辑</a> | " +
                            "<a href='javascript:;' onclick='UserDelete("+data.uid+")'>删除</a> </td>" +
                            "        </tr>")
                    }
                }
            }
            dialog.hide()
        })
    }
</script>

六.运行

访问 index.html 即可, 效果如下, 原生html+css实现. 虽然丑了一点,但是麻雀虽小,五脏俱全,凑合着看下 (^_^)

1460000020871869

完整代码已放到了github

https://github.com/gohouse/go...


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK