概述
如果您没有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私教~
















![[C++] 容器适配器:深入理解Stack与Queue的底层原理](https://img-blog.csdnimg.cn/img_convert/f131b93eba44df4ebf9d71cdb58a4611.png)


