半小时快速入门golang完成简单的web用户管理
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实现. 虽然丑了一点,但是麻雀虽小,五脏俱全,凑合着看下 (^_^)
完整代码已放到了github
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK