欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

go-zero使用goctl生成mongodb的操作使用方法

 更新時間:2024年06月24日 09:56:39   作者:特立獨(dú)行的貓a  
mongodb是一種高性能、開源、文檔型的nosql數(shù)據(jù)庫,被廣泛應(yīng)用于web應(yīng)用、大數(shù)據(jù)以及云計算領(lǐng)域,goctl model 為 goctl 提供的數(shù)據(jù)庫模型代碼生成指令,目前支持 MySQL、PostgreSQL、Mongo 的代碼生成,本文給大家介紹了go-zero使用goctl生成mongodb的操作使用方法

MongoDB簡介

mongodb是一種高性能、開源、文檔型的nosql數(shù)據(jù)庫,被廣泛應(yīng)用于web應(yīng)用、大數(shù)據(jù)以及云計算領(lǐng)域。

在使用MongoDB之前,需要先在您的系統(tǒng)中安裝MongoDB。在Linux系統(tǒng)下,可以通過如下命令安裝:

sudo apt-get install mongodb

MongoDB的優(yōu)勢

1. 強(qiáng)大的靈活性

MongoDB是一個面向文檔的數(shù)據(jù)庫,它使用BSON(二進(jìn)制JSON)格式來存儲數(shù)據(jù)。相比之下,MySQL是一個關(guān)系型數(shù)據(jù)庫,使用表格來存儲數(shù)據(jù)。這使得MongoDB更加靈活,可以存儲不同結(jié)構(gòu)的文檔。例如,我們可以在同一個集合中存儲不同類型的文檔,而MySQL需要創(chuàng)建多個表來存儲不同類型的數(shù)據(jù)。

2. 高性能的讀寫操作

由于MongoDB使用BSON格式存儲數(shù)據(jù),并且數(shù)據(jù)存儲在文檔中,它可以更快地讀寫數(shù)據(jù)。此外,MongoDB還支持內(nèi)置的復(fù)制和分片機(jī)制,可用于處理高并發(fā)的讀寫操作。相比之下,MySQL需要通過SQL查詢語句來讀寫數(shù)據(jù),這通常比MongoDB的操作要慢一些。

3. 分布式擴(kuò)展性

MongoDB可以輕松地進(jìn)行水平擴(kuò)展,即通過添加更多的節(jié)點(diǎn)來增加存儲容量和處理能力。這種分布式架構(gòu)使得MongoDB能夠處理大量數(shù)據(jù)和高并發(fā)請求。與之相比,MySQL在處理大規(guī)模數(shù)據(jù)和高并發(fā)情況下的擴(kuò)展性有限。

4. 靈活的數(shù)據(jù)模型

MongoDB的數(shù)據(jù)模型允許我們使用嵌套文檔和數(shù)組來表示復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。這使得數(shù)據(jù)的存儲和查詢更加方便,無需進(jìn)行多個表之間的連接操作。例如,我們可以在一個文檔中存儲一個訂單及其相關(guān)的所有產(chǎn)品,并且可以輕松地查詢和更新這個文檔。相比之下,MySQL需要通過多個表和連接操作來實現(xiàn)類似的功能。

對比mysql的操作

在數(shù)據(jù)庫的操作上與mysql有很大不同。畢竟一個是非關(guān)系型,一個是關(guān)系型數(shù)據(jù)庫。接下來從python代碼上先來直觀感受下二者的不同。

python操作mogodb示例

# MongoDB示例
 
# 連接到MongoDB數(shù)據(jù)庫
from pymongo import MongoClient
client = MongoClient('mongodb://localhost:27017/')
 
# 獲取數(shù)據(jù)庫和集合對象
db = client['mydb']
collection = db['mycollection']
 
# 插入一條文檔
data = {'name': 'John', 'age': 25}
collection.insert_one(data)
 
# 查詢文檔
result = collection.find_one({'name': 'John'})
print(result)
 
# 關(guān)閉連接
client.close()

mysql的python 示例

-- MySQL示例
 
-- 連接到MySQL數(shù)據(jù)庫
import mysql.connector
cnx = mysql.connector.connect(user='root', password='password', host='localhost', database='mydb')
 
-- 獲取游標(biāo)
cursor = cnx.cursor()
 
-- 插入一條記錄
sql = "INSERT INTO mytable (name, age) VALUES (%s, %s)"
values = ('John', 25)
cursor.execute(sql, values)
cnx.commit()
 
-- 查詢記錄
sql = "SELECT * FROM mytable WHERE name = 'John'"
cursor.execute(sql)
result = cursor.fetchone()
print(result)
 
-- 關(guān)閉連接
cursor.close()
cnx.close()

通過以上示例,可以看到MongoDB使用了面向文檔的操作方式,數(shù)據(jù)以JSON格式存儲在集合中,并且不需要事先定義表結(jié)構(gòu)。而MySQL需要使用SQL語句來進(jìn)行數(shù)據(jù)的插入和查詢,需要提前定義表結(jié)構(gòu)。

總的來說,MongoDB在靈活性、高性能讀寫、分布式擴(kuò)展性和靈活的數(shù)據(jù)模型方面相對于MySQL有許多優(yōu)勢。當(dāng)處理需要存儲和查詢復(fù)雜數(shù)據(jù)結(jié)構(gòu)、大規(guī)模數(shù)據(jù)和高并發(fā)請求時,MongoDB是一個更好的選擇。

goctl的mongodb代碼生成

goctl model 為 goctl 提供的數(shù)據(jù)庫模型代碼生成指令,目前支持 MySQL、PostgreSQL、Mongo 的代碼生成,MySQL 支持從 sql 文件和數(shù)據(jù)庫連接兩種方式生成,PostgreSQL 僅支持從數(shù)據(jù)庫連接生成。

goctl model 為go-zero下的工具模塊中的組件之一,目前支持MongoDB進(jìn)行model層代碼生成。官網(wǎng)有對MySQL的使用方法,但是沒有對MongoDB的使用進(jìn)行講解,那么我下面介紹goctl model對MongoDB的使用方法。

Mongo 模型層代碼的生成不同于 MySQL,MySQL 可以從 scheme_information 庫中讀取到一張表的信息(字段名稱,數(shù)據(jù)類型,索引等), 而 Mongo 是文檔型數(shù)據(jù)庫,我們暫時無法從 db 中讀取某一條記錄來實現(xiàn)字段信息獲取。

Usage:                                                                           
  goctl model mongo [flags]                                                      
                                                                                 
Flags:                                                                           
      --branch string   The branch of the remote repo, it does work with --remote
  -c, --cache           Generate code with cache [optional]                      
  -d, --dir string      The target dir
  -e, --easy            Generate code with auto generated CollectionName for easy declare [optional]
  -h, --help            help for mongo
      --home string     The goctl home path of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority
      --remote string   The remote git repo of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority
                        The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure
      --style string    The file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]
  -t, --type strings    Specified model type name

各個參數(shù)的含義,主要用的是 -e -dir -t
-e表示的是生成一個簡單的增刪改查接口,-dir是生成文檔放在的目錄
-t是生成文件的前綴名稱
-c是帶緩存的 

如何使用

goctl model mongo -t User -dir model/user

如何生成model層代碼?執(zhí)行以上命令即可,很簡單,不需要提前編寫什么模型文件,以上命令將自動在model/user目錄下生成模型框架代碼,如果需要擴(kuò)展其他字段類型,直接修改生成的usertypes.go文件。

過程如下:

# enter user home
$ cd ~
 
# make dir named demo 
$ mkdir demo && cd demo
 
# generate mongo code by goctl
$ goctl model mongo --type User --dir cache --cache
 
# view layout
$ tree
.
└── cache
    ├── error.go
    ├── usermodel.go
    ├── usermodelgen.go
    └── usertypes.go
 
1 directory, 4 files

go-zero中mogodb使用

go-zero中mogodb的基礎(chǔ)使用:

package main
 
import (
	"context"
	"time"
 
	"github.com/globalsign/mgo/bson"
	"github.com/zeromicro/go-zero/core/stores/mon"
	"go.mongodb.org/mongo-driver/bson/primitive"
)
 
type Roster struct {
	Id          primitive.ObjectID `bson:"_id"`
	CreateTime  time.Time          `bson:"createTime"`
	DisplayName string             `bson:"displayName"`
}
 
func main() {
	model := mon.MustNewModel("mongodb://root:example@127.0.0.1:27017", "db", "user")
 
	r := &Roster{
		Id:          primitive.NewObjectID(),
		CreateTime:  time.Now(),
		DisplayName: "Hello",
	}
	ctx := context.Background()
	_, err := model.InsertOne(ctx, r)
	if err != nil {
		panic(err)
	}
 
	update := bson.M{"$set": bson.M{
		"displayName": "Hello world",
		"createTime":  time.Now(),
	}}
	_, err = model.UpdateByID(ctx, r.Id, update)
	if err != nil {
		panic(err)
	}
 
	r.DisplayName = "Hello world!"
	_, err = model.ReplaceOne(ctx, bson.M{"_id": r.Id}, r)
	if err != nil {
		panic(err)
	}
 
	var tr Roster
	err = model.FindOne(ctx, &tr, bson.M{"_id": r.Id})
	if err != nil {
		panic(err)
	}
}

mongodb官方驅(qū)動使用

再來看下在在golang中的mongodb官方驅(qū)動使用示例:

package main
 
import (
    "context"
    "log"
 
    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)
 
func main() {
    clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
    client, err := mongo.Connect(context.Background(), clientOptions)
    if err != nil {
        log.Fatal(err)
    }
    defer client.Disconnect(context.Background())
 
    coll := client.Database("your_db_name").Collection("user")
 
    // 插入數(shù)據(jù)
    doc := &user.User{
        Id:    "1",
        Name:  "Alice",
        Email: "alice@example.com",
    }
    _, err = coll.InsertOne(context.TODO(), doc)
    if err != nil {
        log.Fatal(err)
    }
 
    // 查詢數(shù)據(jù)
    var result user.User
    err = coll.FindOne(context.TODO(), bson.M{"_id": "1"}).Decode(&result)
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Found user: %+v", result)
 
    // 更新數(shù)據(jù)
    updateResult, err := coll.UpdateOne(
        context.TODO(),
        bson.M{"_id": "1"},
        bson.D{{"$set", bson.D{{"email", "alice.updated@example.com"}}}},
    )
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Modified count: %v", updateResult.ModifiedCount)
 
    // 刪除數(shù)據(jù)
    deleteResult, err := coll.DeleteOne(context.TODO(), bson.M{"_id": "1"})
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("Deleted count: %v", deleteResult.DeletedCount)
}

增刪改查示例

package main
 
import (
	"context"
	"fmt"
	"log"
  "time"
 
	//"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go.mongodb.org/mongo-driver/bson"
)
 
type User struct {
	Name  string `json:"name"`
	Email string `json:"email"`
  Age   int    `bson:"Agg"`
}
// ... 上面User結(jié)構(gòu)體定義 ...
 
func main() {
	// 連接MongoDB
	clientOptions := options.Client().ApplyURI("mongodb://test1:111111@localhost:27017/?tls=false&authSource=test1")
	client, err := mongo.Connect(context.Background(), clientOptions)
	if err != nil {
		log.Fatal(err)
	}
	defer func() {
		if err = client.Disconnect(context.Background()); err != nil {
			log.Fatal(err)
		}
	}()
 
	// 解析JSON字符串到User結(jié)構(gòu)體(假設(shè)已經(jīng)完成)
	user := User{Name: "Alice", Email: "alice@example.com",Age:22}
 
	// 選擇數(shù)據(jù)庫和集合
	collection := client.Database("test1").Collection("users")
 
	// 插入文檔
	insertResult, err := collection.InsertOne(context.TODO(), user)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Inserted ID:", insertResult.InsertedID)
 
	// 插入文檔
	doc := bson.D{{"name", "Alice1"}, {"age", 30}, {"createdAt", time.Now()}}
	insertResult, err = collection.InsertOne(context.TODO(), doc)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Inserted ID:", insertResult.InsertedID)
 
	// 更新文檔
	filter := bson.D{{"name", "Alice1"}}
	update := bson.D{{"$set", bson.D{{"age", 31}}}}
	updateResult, err := collection.UpdateOne(context.TODO(), filter, update)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Modified Count:", updateResult.ModifiedCount)
 
	// 刪除文檔
  filter = bson.D{{"age", 22}}
	deleteResult, err := collection.DeleteOne(context.TODO(), filter)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Deleted Count:", deleteResult.DeletedCount)
 
	// 查找單個文檔
	var singleResult bson.M
	err = collection.FindOne(context.TODO(), bson.D{}).Decode(&singleResult)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Single Document:", singleResult)
 
	// 查找所有文檔
	cursor, err := collection.Find(context.TODO(), bson.D{})
	if err != nil {
		log.Fatal(err)
	}
	defer cursor.Close(context.TODO())
 
	for cursor.Next(context.TODO()) {
		var result bson.M
		err := cursor.Decode(&result)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println("Document:", result)
	}
 
	// 過濾查找
	filteredCursor, err := collection.Find(context.TODO(), bson.D{{"age", bson.D{{"$gt", 31}}}})
	if err != nil {
		log.Fatal(err)
	}
	defer filteredCursor.Close(context.TODO())
 
	for filteredCursor.Next(context.TODO()) {
		var filteredDoc bson.M
		err := filteredCursor.Decode(&filteredDoc)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println("Filtered Document:", filteredDoc)
	}
}

注意事項

示例中的bson.D 和 bson.M 都是Go語言中用于表示MongoDB的BSON文檔的數(shù)據(jù)類型,但它們之間存在一些關(guān)鍵的區(qū)別 。

bson.D (Ordered Dictionary),bson.D是一個有序的字典類型,其中元素按照它們被定義的順序排列。它是一個包含了鍵值對的切片,其中每一個元素都是一個兩元素的數(shù)組,第一個元素是字符串(字段名),第二個元素可以是任意類型(字段值)。當(dāng)你需要按照特定順序來定義BSON文檔的字段時,使用它。

bson.M (Map),bson.M是一個無序的映射類型,基于Go語言的map[string]interface{},用于表示不關(guān)心順序的鍵值對集合。用途: 更適合用于構(gòu)建動態(tài)查詢條件或者不需要保持特定字段順序的情況。如:

query := bson.M{"name": "Alice", "age": bson.M{"$gt": 30}}

對于大多數(shù)常規(guī)的查詢構(gòu)建,特別是當(dāng)字段不是嚴(yán)格按照順序組織時用它。當(dāng)文檔的結(jié)構(gòu)是動態(tài)生成或者需要頻繁修改時,bson.M提供了更靈活的鍵值對添加和管理方式。

在Go語言中,使用mongo-go-drive驅(qū)動,需r將JSON字符串轉(zhuǎn)換為結(jié)構(gòu)體,才存儲到MongoDB中。如果你有一個JSON字符串,需要將其解析到Go的結(jié)構(gòu)體中。

直接將JSON字符串存入MongoDB并非最佳實踐,因為MongoDB使用BSON(Binary JSON)作為存儲格式,雖然BSON與JSON相似,但直接存儲JSON字符串會導(dǎo)致數(shù)據(jù)以文本形式存在,喪失了BSON的一些優(yōu)勢,如高效的查詢和索引能力。

然而,如果你確實需要將JSON字符串原樣存儲到MongoDB中(例如,作為文檔的一個字段),可以通過將JSON字符串作為文檔的一個鍵值對插入。

如果golang的結(jié)構(gòu)體不增加bson標(biāo)簽,能否成功寫入mongodb?

為何有了json標(biāo)簽,還要bson標(biāo)簽?zāi)兀?/p>

盡管從表面上看,為BSON序列化單獨(dú)定義標(biāo)簽似乎增加了些冗余,但實際上,這樣的設(shè)計提高了代碼的清晰度、靈活性和對MongoDB特性的直接支持。

即使Go語言的結(jié)構(gòu)體沒有顯式地增加bson標(biāo)簽,你仍然可以成功地將結(jié)構(gòu)體實例寫入MongoDB。mongo-go-driver會按照結(jié)構(gòu)體字段的名稱來映射到BSON文檔的鍵名。但是,這種方式有一些限制和注意事項:

字段名稱:如果沒有bson標(biāo)簽,MongoDB驅(qū)動會直接使用Go結(jié)構(gòu)體字段名作為BSON文檔的鍵。這意味著字段名必須符合MongoDB的命名規(guī)范,且大小寫敏感性會得到保留。這可能導(dǎo)致查詢時需要精確匹配字段名的大小寫。

嵌套結(jié)構(gòu)體:對于嵌套的結(jié)構(gòu)體字段,如果不使用bson標(biāo)簽來指定嵌套層次或別名,那么嵌套結(jié)構(gòu)體的字段會扁平化到同一層級,可能導(dǎo)致數(shù)據(jù)結(jié)構(gòu)與預(yù)期不符。

忽略字段:如果想讓某些字段不被序列化到MongoDB,沒有bson標(biāo)簽就無法直接實現(xiàn)這一點(diǎn)。默認(rèn)情況下,所有未標(biāo)記的公開字段都會被序列化。

特殊類型處理:對于Go中的某些類型,如時間time.Time,如果沒有使用bson標(biāo)簽指定其為日期類型(如bson:"date"),它們會被序列化為BSON的字符串或其他默認(rèn)格式,可能不符合MongoDB的最佳實踐。

因此,雖然不加bson標(biāo)簽可以工作,但在很多實際應(yīng)用場景中,為了更好地控制數(shù)據(jù)的序列化和反序列化行為,以及確保數(shù)據(jù)的一致性和查詢效率,建議還是使用bson標(biāo)簽來明確指定字段映射規(guī)則。

model模型的方式使用

具體的實例化方法,參照goctl模型層的使用,在internal/svc/servicecontext.go 中完成模型的連接和實例化。比較簡單,具體根據(jù)需要更改。

package svc
 
import "myprj/internal/config"
 
//手動代碼
import "myprj/rpc/model"
 
type ServiceContext struct {
	Config config.Config
	Model  model.NewUserModel// 手動代碼
}
 
func NewServiceContext(c config.Config) *ServiceContext {
	return &ServiceContext{
		Config: c,
		Model:  model.NewUserModel(c.DataSource, c.Cache), // 手動代碼
	}
}

以上就是go-zero使用goctl生成mongodb的操作使用方法的詳細(xì)內(nèi)容,更多關(guān)于go-zero goctl生成mongodb的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go語言如何處理HTTP身份驗證教程示例

    Go語言如何處理HTTP身份驗證教程示例

    這篇文章主要為大家介紹了Go語言如何處理HTTP身份驗證教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • Go語言映射內(nèi)部實現(xiàn)及基礎(chǔ)功能實戰(zhàn)

    Go語言映射內(nèi)部實現(xiàn)及基礎(chǔ)功能實戰(zhàn)

    這篇文章主要為大家介紹了Go語言映射的內(nèi)部實現(xiàn)和基礎(chǔ)功能實戰(zhàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>
    2022-03-03
  • GoFrame 框架緩存查詢結(jié)果的示例詳解

    GoFrame 框架緩存查詢結(jié)果的示例詳解

    GoFrame的gdb對查詢結(jié)果的緩存處理是不是非常的優(yōu)雅。尤其是*gcache.Cache對象采用了適配器設(shè)計模式,可以輕松實現(xiàn)從單進(jìn)程內(nèi)存緩存切換為分布式的Redis緩存,本文重點(diǎn)給大家介紹GoFrame 如何優(yōu)雅的緩存查詢結(jié)果,感興趣的朋友一起看看吧
    2022-06-06
  • Go語言實現(xiàn)一個簡單生產(chǎn)者消費(fèi)者模型

    Go語言實現(xiàn)一個簡單生產(chǎn)者消費(fèi)者模型

    本文主要介紹了Go語言實現(xiàn)一個簡單生產(chǎn)者消費(fèi)者模型,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • 詳解go-zero如何使用validator進(jìn)行參數(shù)校驗

    詳解go-zero如何使用validator進(jìn)行參數(shù)校驗

    這篇文章主要介紹了如何使用validator庫做參數(shù)校驗的一些十分實用的使用技巧,包括翻譯校驗錯誤提示信息、自定義提示信息的字段名稱、自定義校驗方法等,感興趣的可以了解下
    2024-01-01
  • 7分鐘讀懂Go的臨時對象池pool以及其應(yīng)用場景

    7分鐘讀懂Go的臨時對象池pool以及其應(yīng)用場景

    這篇文章主要給大家介紹了關(guān)于如何通過7分鐘讀懂Go的臨時對象池pool以及其應(yīng)用場景的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或使用Go具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧
    2018-11-11
  • Go語言Elasticsearch數(shù)據(jù)清理工具思路詳解

    Go語言Elasticsearch數(shù)據(jù)清理工具思路詳解

    這篇文章主要介紹了Go語言Elasticsearch數(shù)據(jù)清理工具思路詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-10-10
  • Go語言實現(xiàn)定時器的方法

    Go語言實現(xiàn)定時器的方法

    這篇文章主要介紹了Go語言實現(xiàn)定時器的方法,涉及Go語言時間操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • Golang拾遺之實現(xiàn)一個不可復(fù)制類型詳解

    Golang拾遺之實現(xiàn)一個不可復(fù)制類型詳解

    在這篇文章中我們將實現(xiàn)一個無法被復(fù)制的類型,順便加深對引用類型、值傳遞以及指針的理解。文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2023-02-02
  • go語言在請求http時加入自定義http header的方法

    go語言在請求http時加入自定義http header的方法

    這篇文章主要介紹了go語言在請求http時加入自定義http header的方法,實例分析了Go語言http請求的原理與操作技巧,需要的朋友可以參考下
    2015-03-03

最新評論