一.课程目标
- 本课程目标是让新手能够在最短的时间内了解到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
方法
// 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 .
浏览器显示如下内容, 则表示成功.
{
"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
golang用户管理示例
欢迎来到golang入门用户管理api服务系统
uid
用户名
年龄
操作
2. 编写增加和修改的模态框弹层
3. 编写JavaScript
六.运行
开启gin静态文件服务器
...
// 静态文件服务
router.Static("/html","./")
...
访问 http://localhost:8080/html 即可, 或者直接打开(index.html
) , 效果如下, 原生html+css实现. 虽然丑了一点,但是麻雀虽小,五脏俱全,凑合着看下(^_^)
完整代码已放到了github
https://github.com/gohouse/go...