前言
本文是探讨的是"Go高级之Gin框架和Mongodb数据库的联动
"
此文章是个人学习归纳的心得,掘金首发,未经允许,严禁转载,如有不对, 还望斧正, 感谢!
为什么是Mongodb数据库?
这次总结,主要还是我之前打算用Gin写一个自己的个人博客网站来练手,我没有选择常用的MySQL,而是打算使用MongoDB作为个人博客网站数据库,有以下几点原因:
-
模式灵活性:
- MongoDB是一个无模式数据库,这意味着可以在不同的文档中存储不同的数据结构。对于博客文章和评论这样的应用,内容的结构可能会随时间发生变化,MongoDB可以让我轻松地调整存储的数据结构而无需修改整个数据库。
-
文档导向:
- MongoDB存储的是文档(通常是JSON格式),这对于内容管理系统来说是自然和直观的。可以把一篇文章和它的评论作为一个文档来存储,这样在查询时可以更快地检索到所有相关信息。
-
水平扩展:
- MongoDB支持自动分片,允许数据库水平扩展,这意味着可以通过添加更多的服务器来提高数据库的容量和吞吐量。虽然个人博客可能不需要这样的扩展能力,但这为将来的增长提供了便利。
-
读写性能:
- 对于读写密集型的应用,MongoDB提供了优秀的性能。特别是在处理大量的读写操作时,例如博客评论,MongoDB的性能通常比MySQL更优。
-
强大的查询语言:
- MongoDB提供了一个功能丰富的查询语言,允许执行复杂的查询和数据聚合,这对于数据分析和报告很有用。
与MySQL相比,MongoDB的这些特性更适合快速变化和不需要严格ACID事务的网站。MySQL作为一个关系型数据库,它的优势在于结构化查询语言(SQL)、事务完整性和成熟的生态系统。
其实也不是全是上面的原因,我们要走出自己的舒适区,多去尝试新的东西,这样我们才能最快进步,其实还有一个原因,go语言的缔造者在创造go之前就参与制定了json的规则,然后go和json的契合度非常高,而Mongodb数据库很适合json格式的数据,所以,你懂的。
go驱动链接Mongodb数据库
先安装Mongodb数据库
这个的话,网上有很多教程,我就不提了,和mysql一样的,我们用数据库之前,也要先安装的,安装好了之后,我们就可以启动了,启动之后,这个服务就会占用27017端口
安装驱动
打开终端或命令提示符,执行以下命令来安装 mongo-go-driver
:
go
go get go.mongodb.org/mongo-driver
具体的代码
go
package DB
import (
"context"
"fmt"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"log"
)
// Client 定义一个全局变量,可以由其他包导入使用
var Client *mongo.Client
func MongodbJoin() {
// 连接到MongoDB,我这些配置是在其他包里面
//clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
clientOptions := options.Client().ApplyURI("mongodb://" + MongodbHost + ":" + MongodbPort)
var err error
Client, err = mongo.Connect(context.Background(), clientOptions)
if err != nil {
fmt.Println("数据库连接失败!!!")
log.Fatal(err)
}
fmt.Println("数据库连接成功!")
// 确保在最后关闭链接
defer func() {
if err := Client.Disconnect(context.Background()); err != nil {
log.Fatal(err)
}
fmt.Println("已经和Mongodb数据库断开链接!")
}()
// 获取数据库和集合
db := Client.Database("myblogmongodb")
usersCollection := db.Collection("users")
articlesCollection := db.Collection("articles")
rootusersCollection := db.Collection("rootusers")
// 创建示例文档并插入到集合中
user := User{
}
// 插入
_, err = usersCollection.InsertOne(context.Background(), user)
if err != nil {
log.Fatal(err)
}
// 创建
article := Article{
}
// 插入
_, err = articlesCollection.InsertOne(context.Background(), article)
if err != nil {
log.Fatal(err)
}
// 创建
rootuser := RootUser{
}
// 插入
_, err = rootusersCollection.InsertOne(context.Background(), rootuser)
if err != nil {
log.Fatal(err)
}
fmt.Println("成功!")
}
在这边,我第一次连接的时候,就开始插入数据了,具体数据结构,我定义在了其他包里面,第一次连接数据库时插入数据是由于MongoDB是一种无模式(Schema-less)
的数据库。
MongoDB是一个文档型数据库
,它不需要事先定义表结构(Schema),而是以文档(Document)的形式存储数据。文档是一个键值对的集合,类似于JSON对象。在MongoDB中,文档可以有不同的结构,不同的文档可以有不同的字段和数据类型。
当我们第一次连接MongoDB数据库时,如果没有插入数据,那么数据库中就不会有任何文档。而在实际应用中,我们通常需要在数据库中创建一些初始数据,以便后续的操作和查询。因此,我们可以在第一次连接数据库时,往表中插入一些初始数据,以满足应用程序的需求。
另外,MongoDB在插入数据时会自动创建集合(Collection)
,如果集合不存在的话。因此,即使在第一次连接数据库时没有创建集合,也可以在插入数据时自动创建。这也是为什么在第一次连接数据库时就可以往表中插入数据的原因之一。
通过MongoDB官方驱动来进行CRUD前的条件锁定
其实CRUD也就是几个API的调用,这个很简单,我们只需要去看函数的用法就行了,我们来看点不一样的,就是和关系型数据库不一样的地方,我们在非关系数据库Mongodb中如何做到数据的精准划分和锁定,关键就在下面查询条件的创建,且听我给你分析。
bson.H:
bson.H{}
是Go语言中MongoDB官方驱动 mongo-go-driver
的一部分。在这个驱动中,bson
代表了 BSON (Binary JSON) 数据格式,它是MongoDB用来存储和网络传输数据的格式。
bson.H
是一个特殊的类型,它是一个map类型的别名,map的键和值都是 interface{}
类型。这种结构允许你以非常灵活的方式构建文档,因为它可以接受任何类型的键值对。它通常用于构建MongoDB操作中的查询和更新文档。
json
codebson.H{
"username": "johndoe",
"age": 30,
}
这里是一个使用 bson.H
的简单例子:
css
codefilter := bson.H{"name": "John Doe"}
update := bson.H{"$set": bson.H{"age": 30}}
在这个例子中,filter
变量定义了一个查询条件,即 name
必须是 "John Doe"。update
变量定义了一个更新操作,它使用MongoDB的 $set
操作符来更新 age
字段的值。
bson.H
是非常便利的,特别是在写快速原型或是处理不需要严格类型的数据时。然而,在处理更复杂的数据或需要类型安全的场景下,你可能会选择使用 bson.D{}
或 bson.M{}
。
bson.D{}
: 表示一个有序的文档,这在需要保持字段顺序时很有用,例如,当字段的顺序会影响MongoDB命令的行为时。bson.M{}
: 类似于bson.H{}
,但是它是一个官方的类型,更常用于官方的文档和例子中。
bson.H
和 bson.M
都是Go语言中用于与MongoDB交互时表示BSON文档的类型,它们都属于 go.mongodb.org/mongo-driver/bson
包。BSON是一种类似于JSON的格式,但它以二进制形式存储,这使得它在MongoDB中非常适合存储和查询。
bson.M:
bson.M
是一个map类型,它的键是字符串,值是任意类型。它是无序的,并且在大多数情况下被用来构建BSON文档。bson.M
被广泛用于MongoDB的查询和更新操作中,因为它的语法简洁明了。
这是如何使用 bson.M
的一个例子:
go
// 构建一个查询条件,寻找名字是"John Doe"的文档
filter := bson.M{"name": "John Doe"}
// 构建一个更新操作,将名字是"John Doe"的文档的年龄设置为30岁
update := bson.M{"$set": bson.M{"age": 30}}
bson.D:
在实际应用中,一般会比较频繁地使用 bson.M
或 bson.D
,而不是 bson.H
。bson.D
是一个有序的文档表示,可以在需要保持键的顺序时使用,这在某些MongoDB的操作中是必要的,例如创建索引。
这是使用 bson.D
的一个例子:
go
// 构建一个有序的文档,这里顺序很重要
doc := bson.D{{"name", "John Doe"}, {"age", 30}}
在这个例子中,doc
会按照 name
和 age
的顺序存储数据,这对于某些操作可能是必需的。如果顺序不重要,你可以使用 bson.M
,它内部是一个Go的map,不保证顺序。
各个结构之间的关系
-
bson.D:它是一个有序的 BSON 文档,类似于 JSON 中的对象。它由一系列的 bson.E 元素组成,每个元素包含一个字段名和对应的值。bson.D 可以通过索引或迭代的方式访问其中的元素。
-
bson.H:它是一个无序的 BSON 文档,类似于 JSON 中的对象。它由一系列的键值对组成,可以通过键来访问对应的值。bson.H 通常用于构建 bson.D。
-
bson.E:它是一个 BSON 文档中的元素,包含一个字段名和对应的值。它可以被添加到 bson.D 中作为一个有序的元素。
-
bson.M:它是一个无序的 BSON 文档,类似于 bson.H,但是它是一个 map 类型。可以通过键来访问对应的值。bson.M 通常用于构建 bson.D。
-
bson.A:它是一个 BSON 文档中的数组,类似于 JSON 中的数组。它可以包含任意类型的元素,并且可以通过索引来访问其中的元素。
bson.D 是一个有序的 BSON 文档,由一系列的 bson.E 元素构成;bson.H 和 bson.M 是无序的 BSON 文档,可以通过键来访问对应的值;bson.E 是一个 BSON 文档中的元素,包含一个字段名和对应的值;bson.A 是一个 BSON 文档中的数组,可以包含任意类型的元素。
总结
操作Mongodb数据库主要是通过bson来对数据进行特征提取和定位,bson是用go写的,和go的契合度很高。