版本 | 更新时间 | 备注 |
---|---|---|
1.0 | 2022.04.19 | v1版本完成 |
1.1 | 2022.04.26 | 新增客户端模块 |
本篇文章主要介绍如何使用golang中的beego框架,遵从MVC架构,并采用restful风格的api去重构我之前写过的学生管理系统,一共实现了5个接口对应五个功能
使用postman或者apifox通过json格式数据与后端交互,为啥没做成页面呢,因为我不会前端,后面学了会来做成一个界面。
不过我做了一个命令行版本的客户端,放在了client目录
关于Python版本的在我前面文章已经实现过,对Python感兴趣的小伙伴可以看下面两篇博客:
Python实现简单学生信息管理程序Python实现简单学生信息管理程序并保存数据至Mysql数据库(附源码) 二、API文档API请求示例与返回请参考: 在线API文档
最关键的两个功能controller与database
5.1 controllerspackage controllers
import (
"encoding/json"
"errors"
"log"
"strconv"
"student/database"
"student/modules"
"github.com/astaxie/beego"
)
type Student struct {
beego.Controller
}
var Stu = new(Student)
// 添加学生信息
func (s *Student) Add() {
// json反序列化
err := json.Unmarshal(s.Ctx.Input.RequestBody, modules.StuRes)
if err != nil {
log.Println("json Unmarshal err", err)
s.Ctx.WriteString(errors.New("json Unmarshal err").Error())
return
}
// 判断学生是否存在
ok := database.IsExits(modules.StuRes.ID)
if ok {
s.Ctx.WriteString("Student already exists")
return
}
// 添加学生信息
err = database.InsertStu(modules.StuRes)
if err != nil {
log.Println("insert student info err", err)
s.Ctx.WriteString(errors.New("insert student info failed").Error())
return
}
s.Ctx.WriteString("save ok")
log.Println("add student info success")
}
// 查看所有学生信息
func (s *Student) Show() {
// 判断是否传入id或者name
id, _ := strconv.Atoi(s.Ctx.Input.Query("id"))
name := s.Ctx.Input.Query("name")
if id != 0 || name != "" {
s.QueryByIDOrName(id, name)
return
}
sturess, err := database.ShowStu(modules.StuRes)
if err != nil {
s.Ctx.WriteString(err.Error())
return
}
s.Data["json"] = sturess
s.ServeJSON()
log.Println("show student info success")
}
func (s *Student) Delete() {
tmp := s.Ctx.Input.Query("id")
id, _ := strconv.Atoi(tmp)
ok := database.IsExits(id)
if !ok {
s.Ctx.WriteString("id not exits")
return
}
err := database.DeleteStu(id)
if err != nil {
s.Ctx.WriteString(err.Error())
return
}
s.Ctx.WriteString("delete ok")
log.Println("delete student info success")
}
func (s *Student) QueryByIDOrName(id int, name string) {
ok := database.IsExits(id)
if !ok {
s.Ctx.WriteString("student not exits")
return
}
sturess, err := database.QueryByIDOrName(id, name)
if err != nil {
s.Ctx.WriteString(err.Error())
return
}
s.Data["json"] = sturess
s.ServeJSON()
log.Println("query student info success")
}
func (s *Student) Update() {
err := json.Unmarshal(s.Ctx.Input.RequestBody, modules.StuRes)
if err != nil {
log.Println("json Unmarshal err", err)
s.Ctx.WriteString(errors.New("json Unmarshal err").Error())
return
}
// 判断学生是否存在
ok := database.IsExits(modules.StuRes.ID)
if ok {
err = database.UpdateStu(modules.StuRes)
if err != nil {
s.Ctx.Output.IsServerError()
log.Println("update student info err", err)
s.Ctx.WriteString(errors.New("update student info failed").Error())
return
}
} else {
s.Ctx.WriteString(errors.New("student not exists").Error())
return
}
s.Ctx.WriteString("update ok")
log.Println("update student info success")
}
func (s *Student) Count() {
count, err := database.Count(modules.StuRes)
if err != nil {
s.Ctx.WriteString(err.Error())
return
}
s.Data["json"] = count
s.ServeJSON()
s.Ctx.WriteString("count ok")
log.Println("count student info success")
}
5.2 database
package database
import (
"student/modules"
"student/common"
)
func InsertStu(stures *modules.StudentRes) error {
_, err := common.Engine.Table("t_student").InsertOne(stures)
if err != nil {
return err
}
return nil
}
// 查询所有信息
func ShowStu(stures *modules.StudentRes) ([]modules.StudentRes, error) {
docList := make([]modules.StudentRes, 0)
err := common.Engine.Table("t_student").Find(&docList)
if err != nil {
return nil, err
}
return docList, nil
}
// 删除学生信息
func DeleteStu(id int) error {
_, err := common.Engine.Table("t_student").Where("id = ?", id).Delete(modules.StudentRes{})
if err != nil {
return err
}
return nil
}
// 测试是否存在
func IsExits(id int) bool {
var stu modules.StudentRes
ok, err := common.Engine.Table("t_student").Where("id = ?", id).Get(&stu)
if ok && err == nil {
return true
}
return false
}
// 根据id或者name查询
func QueryByIDOrName(id int, name string) ([]modules.StudentRes, error) {
docList := make([]modules.StudentRes, 0)
if id != 0 && name == "" {
err := common.Engine.Table("t_student").Where("id = ?", id).Find(&docList)
if err != nil {
return nil, err
}
return docList, nil
}
if name != "" && id == 0 {
err := common.Engine.Table("t_student").Where("name = ?", name).Find(&docList)
if err != nil {
return nil, err
}
return docList, nil
}
if id != 0 && name != "" {
err := common.Engine.Table("t_student").Where("id = ? and name = ?", id, name).Find(&docList)
if err != nil {
return nil, err
}
return docList, nil
}
return nil, nil
}
// 更新学生信息
func UpdateStu(stures *modules.StudentRes) error {
_, err := common.Engine.Table("t_student").Update(stures)
if err != nil {
return err
}
return nil
}
func Count(stures *modules.StudentRes) (int, error) {
count, err := common.Engine.Table("t_student").Count()
if err != nil {
return 0, nil
}
return int(count), nil
}
5.3 客户端代码
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
)
type Student struct {
Id int `json:"id"`
Name string `json:"name"`
Go int `json:"go"`
Python int `json:"python"`
Java int `json:"java"`
}
const (
ServicesURL = "http://127.0.0.1:7788/student"
)
func menu() {
var flag int
fmt.Println("----------------")
fmt.Println("0、退出")
fmt.Println("1、学生录入")
fmt.Println("2、删除学生")
fmt.Println("3、学生修改")
fmt.Println("4、根据id或者name查看学生")
fmt.Println("5、查看所有学生")
fmt.Println("6、查看当前学生数量")
fmt.Println("----------------")
fmt.Printf("请输入指令编号:")
_, err := fmt.Scanln(&flag)
if err != nil {
fmt.Println("您的输入有误,请重新输入")
return
}
if flag == 0 {
fmt.Println("程序退出")
os.Exit(0)
}
handler(flag)
}
func handler(flag int) {
var s = Student{}
switch flag {
case 1:
err := s.stuadd()
if err != nil {
fmt.Println("添加失败", err)
return
}
case 2:
err := s.studel()
if err != nil {
fmt.Println("删除失败", err)
return
}
case 3:
err := s.stuupdate()
if err != nil {
fmt.Println("更新失败", err)
return
}
case 4:
err := s.stusearch()
if err != nil {
return
}
case 5:
err := s.stusearchall()
if err != nil {
return
}
case 6:
count := s.GetCount()
fmt.Printf("当前学生总数为:%d人\n", count)
default:
fmt.Println("请输入0-6之间的数字")
}
}
func (s *Student) stuadd() error {
fmt.Printf("请输入学生id:")
fmt.Scanln(&s.Id)
fmt.Printf("请输入学生name:")
fmt.Scanln(&s.Name)
fmt.Printf("请输入学生go成绩:")
fmt.Scanln(&s.Go)
fmt.Printf("请输入学生python成绩:")
fmt.Scanln(&s.Python)
fmt.Printf("请输入学生java成绩:")
fmt.Scanln(&s.Java)
err := s.SendJson("post")
if err != nil {
return err
}
return nil
}
func (s *Student) SendJson(method string, avg ...interface{}) error {
defer func() {
if err := recover(); err != nil {
fmt.Println("发生错误", err)
}
}()
client := &http.Client{}
buf := new(bytes.Buffer)
enc := json.NewEncoder(buf)
err := enc.Encode(s)
if err != nil {
return err
}
switch strings.ToLower(method) {
case "post":
res, err := http.Post(ServicesURL, "application/json", buf)
if err != nil {
return nil
}
bodyRes, _ := ioutil.ReadAll(res.Body)
fmt.Println("服务端回应:", string(bodyRes))
defer res.Body.Close()
case "delete":
url := fmt.Sprintf("%v?id=%v", ServicesURL, avg[0])
req, err := http.NewRequest("DELETE", url, nil)
if err != nil {
return err
}
res, err := client.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
bodyRes, _ := ioutil.ReadAll(res.Body)
fmt.Println("服务端回应:", string(bodyRes))
case "put":
req, err := http.NewRequest(http.MethodPut, ServicesURL, buf)
if err != nil {
return err
}
res, err := client.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
bodyRes, _ := ioutil.ReadAll(res.Body)
fmt.Println("服务端回应:", string(bodyRes))
case "get":
if avg[0] != nil {
fmt.Println("根据id查询学生信息")
url := fmt.Sprintf("%v?id=%v", ServicesURL, avg[0])
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return err
}
res, err := client.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
bodyRes, _ := ioutil.ReadAll(res.Body)
var stu []Student
err = json.Unmarshal(bodyRes, &stu)
if err != nil {
return err
}
show(stu)
}
if avg[0] == nil {
res, err := http.Get(ServicesURL)
if err != nil {
return nil
}
bodyRes, _ := ioutil.ReadAll(res.Body)
var stu []Student
err = json.Unmarshal(bodyRes, &stu)
if err != nil {
return err
}
show(stu)
defer res.Body.Close()
}
}
return nil
}
func (s *Student) studel() error {
fmt.Printf("请输入需要删除的学生id:")
fmt.Scanln(&s.Id)
err := s.SendJson("delete", s.Id)
if err != nil {
return err
}
return nil
}
func (s *Student) stuupdate() error {
fmt.Printf("请输入要更新的学生id:")
fmt.Scanln(&s.Id)
fmt.Printf("请输入要更新的学生name:")
fmt.Scanln(&s.Name)
fmt.Printf("请输入要更新的学生go成绩:")
fmt.Scanln(&s.Go)
fmt.Printf("请输入要更新的学生python成绩:")
fmt.Scanln(&s.Python)
fmt.Printf("请输入要更新的学生java成绩:")
fmt.Scanln(&s.Java)
err := s.SendJson("put")
if err != nil {
return err
}
return nil
}
func (s *Student) stusearch() error {
fmt.Printf("请输入需要查询的学生id:")
fmt.Scanln(&s.Id)
err := s.SendJson("get", s.Id)
if err != nil {
return err
}
return nil
}
func (s *Student) stusearchall() error {
err := s.SendJson("get", nil)
if err != nil {
return err
}
return nil
}
func (s *Student) GetCount() int {
url := ServicesURL + "/count"
res, err := http.Get(url)
if err != nil {
return 0
}
bodyRes, _ := ioutil.ReadAll(res.Body)
var count int
err = json.Unmarshal(bodyRes, &count)
if err != nil {
return 0
}
return count
}
func show(stu []Student) {
fmt.Println("id\tname\tgo\tpython\tjava")
for _, v := range stu {
fmt.Printf("%v\t%v\t%v\t%v\t%v\n", v.Id, v.Name, v.Go, v.Python, v.Java)
}
}
func main() {
for {
menu()
}
}
六、源码下载
我把源码放在我的cdn上了,点开就能下载
http://qiniu.yunxue521.top/student.zip
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)