Golang 筆記
  • Introduction
  • 安裝Golang
    • 本地編譯與安裝第三方套件
    • 第一個 GO 程式
    • export 與 import
    • 使用 go mod
  • 基本工具
  • DataBase操作
    • MySQL
    • 使用 ORM
    • MongoDB
  • 基本語法
    • Variable
    • BSON
    • JSON
    • 時間相關
    • Interface
    • Error
    • 型別
    • 字串
    • defer
    • panic, recover
    • Channel 與Goroutine
      • 讀寫鎖
      • for select 與 for range
      • UnBuffered channel 與 Buffered channel
    • Function
    • pointer
    • regExp
    • fmt
    • Make vs New
    • struct
    • Array, Slice 陣列
    • map
  • 核心模組
    • Reflect
    • File
    • Signal
    • BuiltIn
    • Sync
    • IO
    • Sort
    • http
    • crypto
    • context
  • 第三方模組
    • Dom Parser
    • gin 框架
    • Websocket
    • Iris框架
      • 讀取 Body 資料
      • 相關範例
    • Fiber 框架
    • 自動重啟 server 工具
    • go-jwt
  • 測試
  • 原始碼解析
  • 常見問題
    • 資料存取不正確
    • Data races
Powered by GitBook
On this page
  • 不錯的文章:
  • 使用 FindOne
  • 使用 Push
  • 完整範例:

Was this helpful?

  1. DataBase操作

MongoDB

Previous使用 ORMNext基本語法

Last updated 3 years ago

Was this helpful?

目前推薦使用 而不是 mgo

不錯的文章:

使用 FindOne

func GetProfile(c *fiber.Ctx) error {
	var result bson.M
	userCollection := config.MI.DB.Collection("user")
	ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
	findOneOpts := options.FindOne()
	singleResult := userCollection.FindOne(ctx, bson.M{"blockchain_address": c.Query("address")}, findOneOpts)

	if err := singleResult.Decode(&result); err == nil {
		fmt.Printf("result: %+v\n", result)
	}

	return c.Status(fiber.StatusOK).JSON(fiber.Map{
		"data":    result,
		"success": true,
		"message": "User profile query successfully",
	})
}

使用 Push

如果結構中有 array 可使用


	opts1 := options.Update().SetUpsert(true)
	filter1 := bson.M{"blockchain_address": Follower.Follower_blockchain_address}
	update1 := bson.M{
		"$push": bson.M{
			"Following": bson.M{
				"blockchain_address": Follower.Following_blockchain_address,
				"create_time":        utils.MakeTimestamp(),
			},
		},
	}
	result1, err1 := userCollection.UpdateOne(ctx, filter1, update1, opts1)

完整範例:

config/db.go

package config

import (
	"context"
	"fmt"
	"log"
	"os"
	"time"

	"github.com/joho/godotenv"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go.mongodb.org/mongo-driver/mongo/readpref"
)

type MongoInstance struct {
	Client *mongo.Client
	DB     *mongo.Database
}

var MI MongoInstance

func ConnectDB() {
	if os.Getenv("APP_ENV") != "production" {
		err := godotenv.Load()
		if err != nil {
			log.Fatal("Error loading .env file")
		}
	}

	client, err := mongo.NewClient(options.Client().ApplyURI(os.Getenv("MONGO_URI")))
	if err != nil {
		log.Fatal(err)
	}

	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	err = client.Connect(ctx)
	if err != nil {
		log.Fatal(err)
	}

	err = client.Ping(ctx, readpref.Primary())
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println("Database connected!")

	MI = MongoInstance{
		Client: client,
		DB:     client.Database(os.Getenv("DB")),
	}
}

models/user.go

package models

import (
	"go.mongodb.org/mongo-driver/bson/primitive"
)

type User struct {
	ID                primitive.ObjectID `json:"_id,omitempty" bson:"_id,omitempty"`
	UserId            string             `json:"userId,omitempty" bson:"userId,omitempty"`
	BlockchainName    string             `json:"blockchainName,omitempty" bson:"blockchainName,omitempty"`
	BlockchainAddress string             `json:"blockchainAddress,omitempty" bson:"blockchainAddress,omitempty"`
	Nickname          string             `json:"nickname,omitempty" bson:"nickname,omitempty"`
	Email             string             `json:"email,omitempty" bson:"email,omitempty"`
	Avatar            string             `json:"avatar,omitempty" bson:"avatar,omitempty"`
	Cover             string             `json:"cover,omitempty" bson:"cover,omitempty"`
	Bio               string             `json:"bio,omitempty" bson:"bio,omitempty"`
	Register_time     string             `json:"register_time,omitempty" bson:"register_time,omitempty"`
	Last_login        string             `json:"last_login,omitempty" bson:"last_login,omitempty"`
	Ip                string             `json:"ip,omitempty" bson:"ip,omitempty"`
}

controllers/userController.go

package controllers

import (
	config "project_name/config"
	models "project_name/models"
	"context"
	"log"
	"math"
	"strconv"
	"time"

	"github.com/gofiber/fiber/v2"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo/options"
)

func GetAllUser(c *fiber.Ctx) error {
	userCollection := config.MI.DB.Collection("user")
	ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)

	var user []models.User

	filter := bson.M{}
	findOptions := options.Find()

	page, _ := strconv.Atoi(c.Query("page", "1"))
	limitVal, _ := strconv.Atoi(c.Query("limit", "10"))
	var limit int64 = int64(limitVal)

	total, _ := userCollection.CountDocuments(ctx, filter)

	findOptions.SetSkip((int64(page) - 1) * limit)
	findOptions.SetLimit(limit)

	cursor, err := userCollection.Find(ctx, filter, findOptions)
	defer cursor.Close(ctx)

	if err != nil {
		return c.Status(fiber.StatusNotFound).JSON(fiber.Map{
			"success": false,
			"message": "user Not found",
			"error":   err,
		})
	}

	for cursor.Next(ctx) {
		var User models.User
		cursor.Decode(&User)
		user = append(user, User)
	}

	last := math.Ceil(float64(total / limit))
	if last < 1 && total > 0 {
		last = 1
	}

	return c.Status(fiber.StatusOK).JSON(fiber.Map{
		"data":      user,
		"total":     total,
		"page":      page,
		"last_page": last,
		"limit":     limit,
	})
}

func AddUser(c *fiber.Ctx) error {
	userCollection := config.MI.DB.Collection("user")
	ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
	User := new(models.User)

	if err := c.BodyParser(User); err != nil {
		log.Println(err)
		return c.Status(400).JSON(fiber.Map{
			"success": false,
			"message": "Failed to parse body",
			"error":   err,
		})
	}

	result, err := userCollection.InsertOne(ctx, User)
	if err != nil {
		return c.Status(500).JSON(fiber.Map{
			"success": false,
			"message": "User failed to insert",
			"error":   err,
		})
	}
	return c.Status(fiber.StatusCreated).JSON(fiber.Map{
		"data":    result,
		"success": true,
		"message": "User inserted successfully",
	})

}

main.go

package main

import (
	"log"
	"os"

	config "project_name/config"
	"project_name/routes"

	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/fiber/v2/middleware/cors"
	"github.com/gofiber/fiber/v2/middleware/logger"
	"github.com/joho/godotenv"
)

func setupRoutes(app *fiber.App) {

	api := app.Group("/api")

	routes.UserRoute(api.Group("/user"))
}

func main() {
	if os.Getenv("APP_ENV") != "production" {
		err := godotenv.Load()
		if err != nil {
			log.Fatal("Error loading .env file")
		}
	}

	app := fiber.New()

	app.Use(cors.New())
	app.Use(logger.New())

	config.ConnectDB()

	setupRoutes(app)

	port := os.Getenv("PORT")
	err := app.Listen(":" + port)

	if err != nil {
		log.Fatal("Error app failed to start")
		panic(err)
	}
}

routes/user.go

package routes

import (
	controllers "project-name/controllers"

	"github.com/gofiber/fiber/v2"
)

func UserRoute(route fiber.Router) {
	route.Get("/", controllers.GetAllUser)
	route.Post("/", controllers.AddUser)
}

.env

MONGO_URI=mongodb://localhost:27017
DB=project-name
PORT=3000
APP_ENV=development

mongo-go-driver
https://github.com/mongodb/mongo-go-driver
https://juejin.cn/post/6908063164726771719