半小時快速上手golang web編程之用戶的增刪改查

一.課程目標

  • 本課程目標是讓新手可以在最短的時間內瞭解到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.建立文件javascript

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

2.編輯main.go,內容以下css

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()
}

運行結果以下:html

$ 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()函數方便快捷調用java

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

初始化用戶表

該表做爲示例的增刪改查對象mysql

// 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.添加路由jquery

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

2.編寫UserAdd方法git

// 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
    }
    // api接口返回
    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 . github

瀏覽器顯示以下內容, 則表示成功.golang

{
    "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) {
    // 默認查詢50條數據
    userList, err := DB().Table("users").OrderBy("uid desc").Limit(50).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>
            年&nbsp;&nbsp;齡: <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>

六.運行

開啓gin靜態文件服務器

...
// 靜態文件服務
router.Static("/html","./")
...

訪問 http://localhost:8080/html 便可, 或者直接打開(index.html) , 效果以下, 原生html+css實現. 雖然醜了一點,可是麻雀雖小,五臟俱全,湊合着看下(^_^)

gorose-gin.png

完整代碼已放到了github

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

相關文章
相關標籤/搜索