讲师中心 微信公众号
AI工具推荐 视频效率加速

使用 Postgres 和 MongoDB 进行 CRUD?

云婷小哥_7800

云婷小哥_7800

发布时间:2024-02-09 14:00:10

|

852人浏览过

|

来源于stackoverflow

转载

使用 postgres 和 mongodb 进行 crud?

php小编西瓜在本文中将带您了解如何使用Postgres和MongoDB进行CRUD操作。Postgres是一种关系型数据库,而MongoDB则是一种文档型数据库。CRUD操作指的是创建(Create)、读取(Read)、更新(Update)和删除(Delete)数据的过程。通过结合使用这两种不同类型的数据库,您可以根据不同的需求选择最适合的数据库进行数据操作,以提高效率和灵活性。接下来,让我们一起来探索这两种数据库在CRUD操作中的应用吧!

问题内容

我对 Go 和后端还很陌生,并且正在参加 Go 实习计划。我们构建了一个连接到 psql 数据库的 CRUD,现在我被告知连接 mongoDB,我们将其用于开发,而 PSQL 将用于生产。 我是否必须从头开始创建用于 mongo 的新处理程序,或者我可以使用相同的处理程序并以某种方式确定正在使用的数据库类型并相应地使用相应的逻辑吗? 例如,我有一个用于用户注册端点的处理程序:

func (ctrl *UserController) Register(c *gin.Context) {
    var user models.User
    if err := c.BindJSON(&user); err != nil {
        c.AbortWithStatusJSON(http.StatusUnprocessableEntity, gin.H{
            "error":   true,
            "message": err.Error(),
        })
        return
    }
    err := ctrl.userService.Register(&user)
    if err != nil {
        c.AbortWithStatusJSON(http.StatusUnprocessableEntity, gin.H{
            "error":   true,
            "message": err.Error(),
        })
        return
    }

    c.JSON(http.StatusCreated, gin.H{
        "message": "successfully created an user",
    })
}

func (svc *UserService) Register(user *models.User) error {
    if svc.userRepo.CheckIfEmailExists(user.Email) {
        return errors.New("user already registered")
    }
    hash, err := svc.generatePasswordHash(user.Password)
    if err != nil {
        return errors.New("err can't register user")
    }

    user.Password = hash

    return svc.userRepo.Insert(user)
}

func (repo *UserRepository) CheckIfEmailExists(mail string) bool {
    var user models.User
    err := repo.dbClient.Debug().Model(models.User{}).Where("email = ?", mail).Find(&user).Error
    return errors.Is(err, gorm.ErrRecordNotFound)
}

func (repo *UserRepository) Insert(user *models.User) error {
    err := repo.dbClient.Debug().Model(models.User{}).Create(user).Error
    if err != nil {
        log.Printf("failed to insert user: %v\n", err)
        return err
    }
    return nil
}

我为 mongo 构建了插入、注册和 CheckIfEmailExists 函数:

func (repo *UserRepository) InsertInMongo(user *models.UserB) error {
    coll := repo.mongoClient.DB.Collection("users")
    _, err := coll.InsertOne(context.TODO(), user)
    if err != nil {
        log.Printf("failed to insert user: %v\n", err)
        return err
    }
    return nil
}

func (svc *UserService) RegisterToMongo(user *models.UserB) error {
    check := svc.userRepo.CheckIfEmailExistsInMongo(user.Email)
    if check {
        return errors.New("user already registered")
    }
    hash, err := svc.generatePasswordHash(user.Password)
    if err != nil {
        return errors.New("err can't register user")
    }
    user.Password = hash
    return svc.userRepo.InsertInMongo(user)
}

func (repo *UserRepository) CheckIfEmailExistsInMongo(email string) bool {
    coll := repo.mongoClient.Collection
    filter := bson.D{{Key: "email", Value: email}}

    count, err := coll.CountDocuments(context.TODO(), filter)
    if err != nil {
        panic(err)
    }
    if count != 0 {
        return true
    }
    return false
}

解决方法

您没有提供如何创建 UserService 的代码。

理想情况下,您应该有一个如下所示的界面:

type UserRepository interface {
    CheckIfEmailExists(mail string) bool
    Insert(user *models.User) error
    …
}

然后,UserService 应该像这样创建:

jquery选项卡式用户注册输入信息表单代码
jquery选项卡式用户注册输入信息表单代码

jquery选项卡式用户注册输入信息表单代码

下载
// We use the interface as param
func NewUserService(userRepo UserRepository) UserService {
    return UserService{
        UserRepo: userRepo
    }
}

并且您将有两个单独的存储库,都实现 UserRepository 接口 - 这意味着它们应该具有与接口相同的名称和相同签名(参数、返回类型)的方法:

mongo_user_repository.go

Type MongoUserRepo struct {
    …
}

func (repo MongoUserRepo) CheckIfEmailExists(mail string) bool {
  … some mongo logic here
}

func (repo MongoUserRepo) Insert(user *models.User) error {
  … some mongo logic here
}

postgres_user_repository.go

type PostgresUserRepo struct {
    …
}

func (repo PostgresUserRepo) CheckIfEmailExists(mail string) bool {
  … some postgres logic here
}

func (repo PostgresUserRepo) Insert(user *models.User) error {
  … some postgres logic here
}

您可以根据用例传递其中任何一个,如下面的(非常糟糕的)示例:

main.go

…

var userService UserService

if os.Getenv(“environment”) == “prod” {
    userService = NewUserService(postgreUserRepo)
} else if os.Getenv(“environment”) == “dev” {
    userService = NewUserService(mongoUserRepo)
}

热门AI工具

更多
音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

相关专题

更多
硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

3088

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

4529

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3709

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

406

2026.01.19

数据库Delete用法
数据库Delete用法

数据库Delete用法:1、删除单条记录;2、删除多条记录;3、删除所有记录;4、删除特定条件的记录。更多关于数据库Delete的内容,大家可以访问下面的文章。

2671

2023.11.13

drop和delete的区别
drop和delete的区别

drop和delete的区别:1、功能与用途;2、操作对象;3、可逆性;4、空间释放;5、执行速度与效率;6、与其他命令的交互;7、影响的持久性;8、语法和执行;9、触发器与约束;10、事务处理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

825

2023.12.29

mongodb和mysql的区别
mongodb和mysql的区别

mongodb和mysql的区别:1、数据模型;2、查询语言;3、扩展性和性能;4、可靠性。本专题为大家提供mongodb和mysql的区别的相关的文章、下载、课程内容,供大家免费下载体验。

755

2023.07.18

mongodb启动命令
mongodb启动命令

MongoDB 是一种开源的、基于文档的 NoSQL 数据库管理系统。本专题提供mongodb启动命令的文章,希望可以帮到大家。

2554

2023.08.08

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

80

2026.09.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
ProcessOn开始使用
ProcessOn开始使用

共0课时 | 0人学习

Mistral 官方手册
Mistral 官方手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn