Go语言+Vue3零基础入门全栈班09 Go语言+MongoDB开发用户管理系统API实战_20240730 课程笔记

news2024/11/25 5:46:50

概述

如果您没有Golang的基础,应该学习如下前置课程。

  • Golang零基础入门
  • Golang面向对象编程
  • Go Web 基础
  • Go语言开发REST API接口_20240728
  • Go语言操作MySQL开发用户管理系统API教程_20240729
  • Redis零基础快速入门_20231227
  • Go+Redis开发用户管理系统API实战_20240730
  • MongoDB快速入门_20240411

基础不好的同学每节课的代码最好配合视频进行阅读和学习,如果基础比较扎实,则阅读本教程巩固一下相关知识点即可,遇到不会的知识点再看视频。

课程特色

本教程录制于2024年7月31日,使用Go1.22版本,基于Goland2024进行开发,采用的技术栈比较新。

每节课控制在十分钟以内,课时精简,每节课都是一个独立的知识点,如果有遗忘,完全可以当做字典来查询,绝不浪费大家的时间。

整个课程从如何连接MongoDB数据库讲起,然后如何创建数据库和表,如何做增删改查,如何讲增删改查的代码改造为REST API接口,层层递进,学习路径平缓。

对于基础较好的同学,本课程还特意讲解了MongoDB官方驱动库的本地化和httprouter的进阶封装使用,基础好的同学也能够从本套课程中学到干货。

Golang是当前国内越来越多的企业正在全面转的一门系统级别的高性能的编程语言,比C语言写法更加的简单,比Python性能更加的好,是新时代的C语言,建议每个程序员都掌握!

视频课程

最近发现越来越多的公司在用Golang了,所以精心整理了一套视频教程给大家,这个是其中的第9部,后续还会有很多。

视频已经录制完成,完整目录截图如下:
在这里插入图片描述

本套课程的特色是每节课都是一个核心知识点,每个视频控制在十分钟左右,精简不废话,拒绝浪费大家的时间。

课程目录

  • 01 概述
  • 02 连接MongoDB
  • 03 创建数据库和表
  • 04 新增数据
  • 05 批量新增数据
  • 06 根据ID查询数据
  • 07 将查询结果解析到结构体列表
  • 08 使用bson.M进行查询
  • 09 使用bson.D实现in查询
  • 10 使用Pipeline和Aggregate实现聚合查询
  • 11 使用UpdateMany修改数据
  • 12 使用DeleteMany删除数据
  • 13 将MongoDB官方驱动库进行本地化
  • 14 实现新增用户的接口并进行测试
  • 15 实现查询所有用户的接口并进行测试
  • 16 封装404错误信息统一返回
  • 17 使用统一返回的404错误信息
  • 18 实现修改用户的接口并进行测试
  • 19 优化统一返回值类型
  • 20 实现根据ID删除用户的接口并进行测试
  • 21 总结

完整代码

01 概述

02 连接MongoDB

package main

import (
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"time"
)

func main() {
	mongoUrl := "mongodb://localhost:27017"
	mongoDb, err := mongo.Connect(
		context.TODO(),
		options.Client().ApplyURI(mongoUrl).SetConnectTimeout(5*time.Second),
	)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(mongoDb)
}

03 创建数据库和表

package main

import (
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"time"
)

func main() {
	// 建立连接
	mongoUrl := "mongodb://localhost:27017"
	mongoDb, err := mongo.Connect(
		context.TODO(),
		options.Client().ApplyURI(mongoUrl).SetConnectTimeout(5*time.Second),
	)
	if err != nil {
		fmt.Println(err)
		return
	}

	// 创建或者选择数据
	db := mongoDb.Database("user_manager")

	// 创建表
	usersCollection := db.Collection("users")
	fmt.Println(usersCollection)
}

04 新增数据

package main

import (
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"time"
)

type User struct {
	Id   int    `bson:"id" json:"id"`
	Name string `bson:"name" json:"name"`
	Age  int    `bson:"age" json:"age"`
}

func main() {
	// 建立连接
	mongoUrl := "mongodb://localhost:27017"
	mongoDb, err := mongo.Connect(
		context.TODO(),
		options.Client().ApplyURI(mongoUrl).SetConnectTimeout(5*time.Second),
	)
	if err != nil {
		fmt.Println(err)
		return
	}

	// 创建或者选择数据
	db := mongoDb.Database("user_manager")

	// 创建表
	usersCollection := db.Collection("users")

	// 新增数据
	zs := User{1, "张三", 23}
	result, err := usersCollection.InsertOne(context.Background(), zs)
	if err != nil {
		fmt.Println(err)
		return
	}

	// 取出ID
	objectID := result.InsertedID.(primitive.ObjectID)
	fmt.Println(objectID)
}

05 批量新增数据

package main

import (
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"time"
)

type User struct {
	Id   int    `bson:"id" json:"id"`
	Name string `bson:"name" json:"name"`
	Age  int    `bson:"age" json:"age"`
}

func main() {
	// 建立连接
	mongoUrl := "mongodb://localhost:27017"
	mongoDb, err := mongo.Connect(
		context.TODO(),
		options.Client().ApplyURI(mongoUrl).SetConnectTimeout(5*time.Second),
	)
	if err != nil {
		fmt.Println(err)
		return
	}

	// 创建或者选择数据
	db := mongoDb.Database("user_manager")

	// 创建表
	usersCollection := db.Collection("users")

	// 新增数据
	data := []interface{}{
		User{1, "张三", 23},
		User{2, "李四", 23},
	}
	result, err := usersCollection.InsertMany(context.Background(), data)
	if err != nil {
		fmt.Println(err)
		return
	}

	// 取出ID
	for _, u := range result.InsertedIDs {
		objectID := u.(primitive.ObjectID)
		fmt.Println(objectID)
	}
}

06 根据ID查询数据

package main

import (
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"time"
)

type User struct {
	Id   int    `bson:"id" json:"id"`
	Name string `bson:"name" json:"name"`
	Age  int    `bson:"age" json:"age"`
}

func main() {
	// 建立连接
	mongoUrl := "mongodb://localhost:27017"
	mongoDb, err := mongo.Connect(
		context.TODO(),
		options.Client().ApplyURI(mongoUrl).SetConnectTimeout(5*time.Second),
	)
	if err != nil {
		fmt.Println(err)
		return
	}

	// 创建或者选择数据
	db := mongoDb.Database("user_manager")

	// 创建表
	usersCollection := db.Collection("users")

	// 查询数据
	query := map[string]int{"id": 1}
	cur, err := usersCollection.Find(
		context.TODO(),
		query,
		options.Find().SetSkip(0),
		options.Find().SetLimit(10),
	)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer cur.Close(context.Background())

	// 反序列化
	for cur.Next(context.Background()) {
		var user User
		if cur.Decode(&user) != nil {
			fmt.Println(err)
			return
		}
		fmt.Println(user)
	}
}

07 将查询结果解析到结构体列表

package main

import (
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"time"
)

type User struct {
	Id   int    `bson:"id" json:"id"`
	Name string `bson:"name" json:"name"`
	Age  int    `bson:"age" json:"age"`
}

func main() {
	// 建立连接
	mongoUrl := "mongodb://localhost:27017"
	mongoDb, err := mongo.Connect(
		context.TODO(),
		options.Client().ApplyURI(mongoUrl).SetConnectTimeout(5*time.Second),
	)
	if err != nil {
		fmt.Println(err)
		return
	}

	// 创建或者选择数据
	db := mongoDb.Database("user_manager")

	// 创建表
	usersCollection := db.Collection("users")

	// 查询数据
	query := map[string]int{"id": 1}
	cur, err := usersCollection.Find(
		context.TODO(),
		query,
		options.Find().SetSkip(0),
		options.Find().SetLimit(10),
	)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer cur.Close(context.Background())

	// 反序列化
	var users []User
	err = cur.All(context.Background(), &users)
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, user := range users {
		fmt.Println(user)
	}
}

08 使用bson.M进行查询

package main

import (
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"time"
)

type User struct {
	Id   int    `bson:"id" json:"id"`
	Name string `bson:"name" json:"name"`
	Age  int    `bson:"age" json:"age"`
}

func main() {
	// 建立连接
	mongoUrl := "mongodb://localhost:27017"
	mongoDb, err := mongo.Connect(
		context.TODO(),
		options.Client().ApplyURI(mongoUrl).SetConnectTimeout(5*time.Second),
	)
	if err != nil {
		fmt.Println(err)
		return
	}

	// 创建或者选择数据
	db := mongoDb.Database("user_manager")

	// 创建表
	usersCollection := db.Collection("users")

	// 查询数据
	query := bson.M{"id": 1}
	cur, err := usersCollection.Find(
		context.TODO(),
		query,
		options.Find().SetSkip(0),
		options.Find().SetLimit(10),
	)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer cur.Close(context.Background())

	// 反序列化
	var users []User
	err = cur.All(context.Background(), &users)
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, user := range users {
		fmt.Println(user)
	}
}

09 使用bson.D实现in查询

package main

import (
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"time"
)

type User struct {
	Id   int    `bson:"id" json:"id"`
	Name string `bson:"name" json:"name"`
	Age  int    `bson:"age" json:"age"`
}

func main() {
	// 建立连接
	mongoUrl := "mongodb://localhost:27017"
	mongoDb, err := mongo.Connect(
		context.TODO(),
		options.Client().ApplyURI(mongoUrl).SetConnectTimeout(5*time.Second),
	)
	if err != nil {
		fmt.Println(err)
		return
	}

	// 创建或者选择数据
	db := mongoDb.Database("user_manager")

	// 创建表
	usersCollection := db.Collection("users")

	// 查询数据
	query := bson.D{{
		"name",
		bson.D{{ // D表示Document 文档
			"$in",
			bson.A{"张三", "李四"}, // A 表示Array 数组
		}},
	}}
	cur, err := usersCollection.Find(
		context.TODO(),
		query,
		options.Find().SetSkip(0),
		options.Find().SetLimit(10),
	)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer cur.Close(context.Background())

	// 反序列化
	var users []User
	err = cur.All(context.Background(), &users)
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, user := range users {
		fmt.Println(user)
	}
}

10 使用Pipeline和Aggregate实现聚合查询

package main

import (
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"time"
)

type User struct {
	Id   int    `bson:"id" json:"id"`
	Name string `bson:"name" json:"name"`
	Age  int    `bson:"age" json:"age"`
}

func main() {
	// 建立连接
	mongoUrl := "mongodb://localhost:27017"
	mongoDb, err := mongo.Connect(
		context.TODO(),
		options.Client().ApplyURI(mongoUrl).SetConnectTimeout(5*time.Second),
	)
	if err != nil {
		fmt.Println(err)
		return
	}

	// 创建或者选择数据
	db := mongoDb.Database("user_manager")

	// 创建表
	usersCollection := db.Collection("users")

	// 查询数据
	groupStage := mongo.Pipeline{bson.D{
		{"$group", bson.D{
			{"_id", "$name"},
			{"count", bson.D{
				{"$sum", 1},
			}},
		}},
	}}
	cur, err := usersCollection.Aggregate(
		context.TODO(),
		groupStage,
	)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer cur.Close(context.Background())

	// 反序列化
	var users []bson.M
	err = cur.All(context.Background(), &users)
	if err != nil {
		fmt.Println(err)
		return
	}
	for _, user := range users {
		fmt.Println(user)
	}
}

11 使用UpdateMany修改数据

package main

import (
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"time"
)

type User struct {
	Id   int    `bson:"id" json:"id"`
	Name string `bson:"name" json:"name"`
	Age  int    `bson:"age" json:"age"`
}

func main() {
	// 建立连接
	mongoUrl := "mongodb://localhost:27017"
	mongoDb, err := mongo.Connect(
		context.TODO(),
		options.Client().ApplyURI(mongoUrl).SetConnectTimeout(5*time.Second),
	)
	if err != nil {
		fmt.Println(err)
		return
	}

	// 创建或者选择数据
	db := mongoDb.Database("user_manager")

	// 创建表
	usersCollection := db.Collection("users")

	// 更新数据
	query := bson.M{"id": 1}
	update := bson.M{"$set": bson.M{"age": 33}}
	result, err := usersCollection.UpdateMany(
		context.TODO(),
		query,
		update,
	)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(result.ModifiedCount)
}

12 使用DeleteMany删除数据

package main

import (
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"time"
)

type User struct {
	Id   int    `bson:"id" json:"id"`
	Name string `bson:"name" json:"name"`
	Age  int    `bson:"age" json:"age"`
}

func main() {
	// 建立连接
	mongoUrl := "mongodb://localhost:27017"
	mongoDb, err := mongo.Connect(
		context.TODO(),
		options.Client().ApplyURI(mongoUrl).SetConnectTimeout(5*time.Second),
	)
	if err != nil {
		fmt.Println(err)
		return
	}

	// 创建或者选择数据
	db := mongoDb.Database("user_manager")

	// 创建表
	usersCollection := db.Collection("users")

	// 删除数据
	query := bson.M{"id": 1}
	result, err := usersCollection.DeleteMany(
		context.TODO(),
		query,
	)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(result.DeletedCount)
}

13 将MongoDB官方驱动库进行本地化

14 实现新增用户的接口并进行测试

服务端代码:

package main

import (
	"context"
	"fmt"
	"github.com/zhangdapeng520/zdpgo_httprouter"
	"github.com/zhangdapeng520/zdpgo_mongo/mongo"
	"github.com/zhangdapeng520/zdpgo_mongo/mongo/options"
	"net/http"
	"time"
)

var (
	// 建立连接
	mongoUrl   = "mongodb://localhost:27017"
	mongoDb, _ = mongo.Connect(
		context.TODO(),
		options.Client().ApplyURI(mongoUrl).SetConnectTimeout(5*time.Second),
	)
	// 创建或者选择数据
	db = mongoDb.Database("user_manager")
	// 创建表
	usersCollection = db.Collection("users")
)

type User struct {
	Id   int64  `bson:"id" json:"id"`
	Name string `bson:"name" json:"name"`
	Age  int    `bson:"age" json:"age"`
}

func RouterAddUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {
	var user User
	zdpgo_httprouter.GetJson(r, &user)

	id := time.Now().UnixNano()
	user.Id = id

	// 新增
	_, err := usersCollection.InsertOne(context.Background(), user)
	if err != nil {
		fmt.Println(err)
		return
	}

	// 返回
	zdpgo_httprouter.ResponseSuccess(w, user)
}

func main() {
	router := zdpgo_httprouter.New()
	router.POST("/user", RouterAddUser)

	server := &http.Server{
		Addr:         "0.0.0.0:8888",
		Handler:      router,
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 5 * time.Second,
	}

	server.ListenAndServe()
}

客户端代码:

package main

import (
	"fmt"
	"github.com/zhangdapeng520/zdpgo_httprouter"
	"io"
)

func main() {
	targetUrl := "http://localhost:8888/user"
	data := map[string]interface{}{
		"name": "王五",
		"age":  35,
	}
	resp, err := zdpgo_httprouter.SendJson("POST", targetUrl, data)
	if err != nil {
		fmt.Println(err)
		return
	}

	body := resp.Body
	bodyBytes, err := io.ReadAll(body)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(bodyBytes))
}

15 实现查询所有用户的接口并进行测试

服务端代码:

package main

import (
	"context"
	"fmt"
	"github.com/zhangdapeng520/zdpgo_httprouter"
	"github.com/zhangdapeng520/zdpgo_mongo/bson"
	"github.com/zhangdapeng520/zdpgo_mongo/mongo"
	"github.com/zhangdapeng520/zdpgo_mongo/mongo/options"
	"net/http"
	"time"
)

var (
	// 建立连接
	mongoUrl   = "mongodb://localhost:27017"
	mongoDb, _ = mongo.Connect(
		context.TODO(),
		options.Client().ApplyURI(mongoUrl).SetConnectTimeout(5*time.Second),
	)
	// 创建或者选择数据
	db = mongoDb.Database("user_manager")
	// 创建表
	usersCollection = db.Collection("users")
)

type User struct {
	Id   int64  `bson:"id" json:"id"`
	Name string `bson:"name" json:"name"`
	Age  int    `bson:"age" json:"age"`
}

func RouterAddUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {
	var user User
	zdpgo_httprouter.GetJson(r, &user)

	id := time.Now().UnixNano()
	user.Id = id

	// 新增
	_, err := usersCollection.InsertOne(context.Background(), user)
	if err != nil {
		fmt.Println(err)
		return
	}

	// 返回
	zdpgo_httprouter.ResponseSuccess(w, user)
}
func RouterGetUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {
	// 查询数据
	query := bson.M{}
	cur, err := usersCollection.Find(
		context.TODO(),
		query,
		options.Find().SetSkip(0),
		options.Find().SetLimit(20),
	)
	if err != nil {
		fmt.Println(err)
		zdpgo_httprouter.ResponseSuccess(w, nil)
		return
	}
	defer cur.Close(context.Background())

	// 反序列化
	var users []User
	err = cur.All(context.Background(), &users)
	if err != nil {
		fmt.Println(err)
		zdpgo_httprouter.ResponseSuccess(w, nil)
		return
	}

	// 返回
	zdpgo_httprouter.ResponseSuccess(w, users)
}

func main() {
	router := zdpgo_httprouter.New()
	router.POST("/user", RouterAddUser)
	router.GET("/user", RouterGetUser)

	server := &http.Server{
		Addr:         "0.0.0.0:8888",
		Handler:      router,
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 5 * time.Second,
	}

	server.ListenAndServe()
}

客户端代码:

package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	targetUrl := "http://localhost:8888/user"
	resp, err := http.Get(targetUrl)
	if err != nil {
		fmt.Println(err)
		return
	}

	body := resp.Body
	bodyBytes, err := io.ReadAll(body)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(bodyBytes))
}

16 封装404错误信息统一返回

17 使用统一返回的404错误信息

18 实现修改用户的接口并进行测试

服务端代码:

package main

import (
	"context"
	"fmt"
	"github.com/zhangdapeng520/zdpgo_httprouter"
	"github.com/zhangdapeng520/zdpgo_mongo/bson"
	"github.com/zhangdapeng520/zdpgo_mongo/mongo"
	"github.com/zhangdapeng520/zdpgo_mongo/mongo/options"
	"net/http"
	"strconv"
	"time"
)

var (
	// 建立连接
	mongoUrl   = "mongodb://localhost:27017"
	mongoDb, _ = mongo.Connect(
		context.TODO(),
		options.Client().ApplyURI(mongoUrl).SetConnectTimeout(5*time.Second),
	)
	// 创建或者选择数据
	db = mongoDb.Database("user_manager")
	// 创建表
	usersCollection = db.Collection("users")
)

type User struct {
	Id   int64  `bson:"id" json:"id"`
	Name string `bson:"name" json:"name"`
	Age  int    `bson:"age" json:"age"`
}

func RouterAddUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {
	var user User
	zdpgo_httprouter.GetJson(r, &user)

	id := time.Now().UnixNano()
	user.Id = id

	// 新增
	_, err := usersCollection.InsertOne(context.Background(), user)
	if err != nil {
		fmt.Println(err)
		return
	}

	// 返回
	zdpgo_httprouter.ResponseSuccess(w, user)
}
func RouterGetUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {
	// 查询数据
	query := bson.M{}
	cur, err := usersCollection.Find(
		context.TODO(),
		query,
		options.Find().SetSkip(0),
		options.Find().SetLimit(20),
	)
	if err != nil {
		fmt.Println(err)
		zdpgo_httprouter.ResponseError404(w, nil)
		return
	}
	defer cur.Close(context.Background())

	// 反序列化
	var users []User
	err = cur.All(context.Background(), &users)
	if err != nil {
		fmt.Println(err)
		zdpgo_httprouter.ResponseError404(w, nil)
		return
	}

	// 返回
	zdpgo_httprouter.ResponseSuccess(w, users)
}
func RouterUpdateUser(w http.ResponseWriter, r *http.Request, ps zdpgo_httprouter.Params) {
	id := ps.ByName("id")
	idInt, _ := strconv.ParseInt(id, 10, 64)

	var user User
	zdpgo_httprouter.GetJson(r, &user)
	user.Id = idInt

	// 更新数据
	query := bson.M{"id": idInt}
	update := bson.M{"$set": bson.M{"name": user.Name, "age": user.Age}}
	result, err := usersCollection.UpdateMany(
		context.TODO(),
		query,
		update,
	)
	if err != nil {
		fmt.Println(err)
		zdpgo_httprouter.ResponseSuccess(w, nil)
		return
	}

	// 返回
	data := map[string]interface{}{
		"modifiedCount": result.ModifiedCount,
		"user":          user,
	}
	zdpgo_httprouter.ResponseSuccess(
		w,
		data,
	)
}

func main() {
	router := zdpgo_httprouter.New()
	router.POST("/user", RouterAddUser)
	router.GET("/user", RouterGetUser)
	router.PUT("/user/:id", RouterUpdateUser)

	server := &http.Server{
		Addr:         "0.0.0.0:8888",
		Handler:      router,
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 5 * time.Second,
	}

	server.ListenAndServe()
}

客户端代码:

package main

import (
	"fmt"
	"github.com/zhangdapeng520/zdpgo_httprouter"
	"io"
)

func main() {
	targetUrl := "http://localhost:8888/user/2"
	data := map[string]interface{}{
		"name": "李四333",
		"age":  35,
	}
	resp, err := zdpgo_httprouter.SendJson("PUT", targetUrl, data)
	if err != nil {
		fmt.Println(err)
		return
	}

	body := resp.Body
	bodyBytes, err := io.ReadAll(body)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(bodyBytes))
}

19 优化统一返回值类型

20 实现根据ID删除用户的接口并进行测试

服务端代码:

package main

import (
	"context"
	"fmt"
	"github.com/zhangdapeng520/zdpgo_httprouter"
	"github.com/zhangdapeng520/zdpgo_mongo/bson"
	"github.com/zhangdapeng520/zdpgo_mongo/mongo"
	"github.com/zhangdapeng520/zdpgo_mongo/mongo/options"
	"net/http"
	"strconv"
	"time"
)

var (
	// 建立连接
	mongoUrl   = "mongodb://localhost:27017"
	mongoDb, _ = mongo.Connect(
		context.TODO(),
		options.Client().ApplyURI(mongoUrl).SetConnectTimeout(5*time.Second),
	)
	// 创建或者选择数据
	db = mongoDb.Database("user_manager")
	// 创建表
	usersCollection = db.Collection("users")
)

type User struct {
	Id   int64  `bson:"id" json:"id"`
	Name string `bson:"name" json:"name"`
	Age  int    `bson:"age" json:"age"`
}

func RouterAddUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {
	var user User
	zdpgo_httprouter.GetJson(r, &user)

	id := time.Now().UnixNano()
	user.Id = id

	// 新增
	_, err := usersCollection.InsertOne(context.Background(), user)
	if err != nil {
		fmt.Println(err)
		return
	}

	// 返回
	zdpgo_httprouter.ResponseSuccess(w, user)
}
func RouterGetUser(w http.ResponseWriter, r *http.Request, _ zdpgo_httprouter.Params) {
	// 查询数据
	query := bson.M{}
	cur, err := usersCollection.Find(
		context.TODO(),
		query,
		options.Find().SetSkip(0),
		options.Find().SetLimit(20),
	)
	if err != nil {
		fmt.Println(err)
		zdpgo_httprouter.ResponseError404(w, nil)
		return
	}
	defer cur.Close(context.Background())

	// 反序列化
	var users []User
	err = cur.All(context.Background(), &users)
	if err != nil {
		fmt.Println(err)
		zdpgo_httprouter.ResponseError404(w, nil)
		return
	}

	// 返回
	zdpgo_httprouter.ResponseSuccess(w, users)
}
func RouterUpdateUser(w http.ResponseWriter, r *http.Request, ps zdpgo_httprouter.Params) {
	id := ps.ByName("id")
	idInt, _ := strconv.ParseInt(id, 10, 64)

	var user User
	zdpgo_httprouter.GetJson(r, &user)
	user.Id = idInt

	// 更新数据
	query := bson.M{"id": idInt}
	update := bson.M{"$set": bson.M{"name": user.Name, "age": user.Age}}
	result, err := usersCollection.UpdateMany(
		context.TODO(),
		query,
		update,
	)
	if err != nil {
		fmt.Println(err)
		zdpgo_httprouter.ResponseSuccess(w, nil)
		return
	}

	// 返回
	data := map[string]interface{}{
		"modifiedCount": result.ModifiedCount,
		"user":          user,
	}
	zdpgo_httprouter.ResponseSuccess(
		w,
		data,
	)
}
func RouterDeleteUser(w http.ResponseWriter, r *http.Request, ps zdpgo_httprouter.Params) {
	id := ps.ByName("id")
	idInt, _ := strconv.ParseInt(id, 10, 64)

	// 删除数据
	query := bson.M{"id": idInt}
	result, err := usersCollection.DeleteMany(
		context.TODO(),
		query,
	)
	if err != nil {
		fmt.Println(err)
		zdpgo_httprouter.ResponseError500(w, nil)
		return
	}

	// 返回
	data := map[string]interface{}{
		"deletedCount": result.DeletedCount,
		"id":           id,
	}
	zdpgo_httprouter.ResponseSuccess(
		w,
		data,
	)
}

func main() {
	router := zdpgo_httprouter.New()
	router.POST("/user", RouterAddUser)
	router.GET("/user", RouterGetUser)
	router.PUT("/user/:id", RouterUpdateUser)
	router.DELETE("/user/:id", RouterDeleteUser)

	server := &http.Server{
		Addr:         "0.0.0.0:8888",
		Handler:      router,
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 5 * time.Second,
	}

	server.ListenAndServe()
}

客户端代码:

package main

import (
	"fmt"
	"github.com/zhangdapeng520/zdpgo_httprouter"
	"io"
)

func main() {
	targetUrl := "http://localhost:8888/user/965490400"
	data := map[string]interface{}{}
	resp, err := zdpgo_httprouter.SendJson("DELETE", targetUrl, data)
	if err != nil {
		fmt.Println(err)
		return
	}

	body := resp.Body
	bodyBytes, err := io.ReadAll(body)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(bodyBytes))
}

总结

本套教程主要讲解Go语言操作MongoDB的基础知识,从零到一的层层递进,从怎么连接MongoDB讲起,然后讲解如何做增删改查,如何讲增删改查的代码改造为REST API接口。

通过本套课程,能帮你入门Go语言操作MongoDB的技术。

如果您需要完整的源码,打赏20元即可。

人生苦短,我用PyGo,我是您身边的Python私教~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1967659.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PG如何实现跨大版本升级

数据库进行升级,是一个再正常不过的功能,比如功能的需要,遇到BUG,安全漏洞等等,具体升级包含子版本升级,主版本升级。如果用过ORACLE的朋友,一定知道,在ORACLE中,如果要实…

dp:221. 最大正方形

221. 最大正方形 看到这个题目真能立马想到dp吗?貌似很难,即使知道是一个dp题也很难想到解法。 直观来看,使用bfs以一个点为中点进行遍历,需要的时间复杂度为 O ( n 2 m 2 ) O(n^2m^2) O(n2m2) 但是可以很容易发现,…

昂科烧录器支持MindMotion灵动微电子的32位微控制器MM32SPIN360C

芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表,其中MindMotion灵动微电子的32位微控制器MM32SPIN360C已经被昂科的通用烧录平台AP8000所支持。 MM32SPIN360C使用高性能的ARM CortexM0为内核的32位微控制器,5V输出的L…

九大原则,轻松构建个人高效SOP

1、原则一、工作汇报SOP SCQA模型(升职加薪的关键!) 清晰定义问题和提出解决方案 类别 关键词 解读 S - Situation 情景 陈述项目背景,目标,愿景 C - Complication 冲突 讲卡点,讲冲突 Q - Question 疑问-问题 这些冲…

vue2 封装插槽组件

安装 element-ui npm install element-ui --save ---force main.js 导入 import Vue from vue; import ElementUI from element-ui; import element-ui/lib/theme-chalk/index.css; import App from ./App.vue; Vue.use(ElementUI); new Vue({ el: #app, render: h > h(Ap…

未来RPA财税的发展前景

近年来,全球数字化进程持续提速,越来越多企业受到效率及运营成本的压力,正努力寻求企业增长发展的新路径,而财务作为企业战略的“大脑”,成为企业数字化转型的重要突破口。RPA技术由于能够自动化各种重复性和繁琐的任务…

如何利用智能电子工牌提高酒店员工的服务技能和沟通效率?

智能电子语音工牌的基本功能 智能电子录音工牌通常集成了录音、语音识别、数据上传等功能,能够在员工与客户互动的过程中实时录制音频,并将数据上传到云端服务器。这些工牌还可能配备定位功能,以便追踪员工的位置和服务轨迹。通过语音识别技…

职场里有3个错觉,如果正好说中你,抓紧醒过来

1.没有我肯定不行。 其实大多数公司里的绝大多数人都可以被替代,无非是在个体层面替代的成本高一点、低一点罢了。 所以千万别高估自己,否则会造成极其严重的误判。 我之前的公司有一个部门,这里面有个员工,专业对口&#xff0…

vue-cli搭建项目笔记

1. 在指定位置打开终端 2. 运行 指令 vue create xtx选择 vue2 等待创建完成。。。。。 大概5.52s完成 3.启动项目 进入 项目 目录 cd xtx 启动 yarn run serve 4. 访问 浏览器 访问 localhost:8080 5. 项目开发 清空项目 App.vue 注意:每一个vue组件中的…

柯桥零基础学韩语韩语俗语韩语日常口语培训

반모반말모드 반말모드 非敬语模式 존모존댓말모드 존댓말모드 敬语模式 2 비담 비담비주얼담당 비주얼 담당, 意思就是颜值担当。 3 보배 보배보조배터리15857575376# 随身充、充电宝 如果单讲单词,是宝贝的意思。网络用语角度理解的话就是充电宝 4 삼귀다…

这4个思维导图软件剪辑就是整理思维的魔法工具。

思维导图作为一个能够帮助我们呈现可视化内容,激发创意以及提高我们记忆力的工具;正在被越来越多的人使用。然而选择一款适合自己的脑图软件,会为我们的学习、工作和生活带来很大的便利,如果你依旧还在寻找的话,不妨看…

SVM解决线性不可分问题

在一个棋盘上杂糅的摆放着黑白两种棋子,要求我们以最快的速度将它们各自分开,这时我们应该如何做呢?也许喜欢金庸武侠的小伙伴已经想到了答案。 假如你是一位拥有深厚内力的大侠,你直接可以拍盘而起,让棋子们飞起来&am…

secExample靶场之java反序列化漏洞复现

我是使用kali虚拟机搭建的靶场,具体搭建步骤可以看我之前的博客内容。 访问靶机地址,打开java反序列化的 点进去后是如图的页面,随便输入一信息。 可以看到敏感信息直接显示在了页面上。 访问192.168.189.141:8080/cors1,可以看到…

揭秘律师界的“超能力”:AI如何让繁琐工作变轻松?

律师朋友们,你们是否也曾为文书堆成山、法规更新追不上、案例分析耗时久而头疼?我懂你们的痛,毕竟,咱也是从那个“人肉检索机”时代走过来的。不过,今天我要分享一个秘密武器——AI工具,它们真的能帮咱们把…

由浅入深的了解进程(3)

进程状态 进程状态1、Linux中的进程状态1、1、进程状态R和S1、2、进程状态T/t1、3、进程状态D1、4、进程状态X和Z 2、僵尸进程3、孤儿进程4、bash概括5、进程的阻塞,挂起和运行5、1、运行5、2、阻塞5、3、挂起 进程状态 任何一个进程都要有自己的代码和数据一样&am…

CSS雷达光波效果(前端雷达光波效果)

前言 CSS雷达光波效果是一种视觉动画效果,常用于模仿雷达扫描或检测的视觉反馈。这种效果通常涉及到动态的圆形或弧形图案,它们从一个中心点向外扩散,类似于水面上的涟漪或雷达扫描线。以下是创建CSS雷达光波效果的一些关键技术和步骤&#…

[C++] 容器适配器:深入理解Stack与Queue的底层原理

文章目录 容器适配器简介deque的缺陷为什么使用deque作为stack和queue的底层默认容器 stack和queue的简单讲解Stack(栈)栈的操作图示栈的相关接口 Queue(队列) Stack和Queue的模拟实现Stack(栈)作为容器适配…

新时代的北斗时空智能:助力节能减排,共筑低碳未来

随着全球环境问题日益加剧,节能减排和低碳生活成为了全世界共同的目标。中国作为一个崛起中的大国,在这一领域肩负着重要的责任。近年来,中国的北斗卫星导航系统(BDS)异军突起,其时空智能技术在多个方面特别…

盘点国内ERP系统,看看你都用过哪一款?

在数字化转型的浪潮中,企业资源计划(ERP)系统已成为企业提升管理效率、优化资源配置的关键工具。国内市场上,众多优秀的ERP软件产品如雨后春笋般涌现,为企业提供了丰富多样的选择。 本文将为您深度盘点10款国产高端ERP软件,重点围绕公司背景、专业实力、产品核心能力、解…

【机器学习】逻辑损失函数的基本概念和探索为什么平方误差损失函数不适用于逻辑回归以及探索逻辑损失函数

引言 在机器学习中,逻辑损失函数(Logistic Loss Function)是用于训练逻辑回归模型的一种损失函数。逻辑回归是一种广泛用于分类问题的模型,特别是用于二分类问题,它的目标是预测一个实例属于两个类别中的一个的概率 文…