个人技术总结——Gorm框架的多表联合查询

这个作业属于哪个课程软件工程-2023年春季
这个作业要求在哪里软件工程实践总结&个人技术总结
这个作业的目标<写上具体方面>
其他参考文献《构建之法》.

目录


技术概述

Gorm框架可以进行多表联合查询,通过多表联合查询可以通过一条sql语句即可完成对数据库多表数据的获取,而不需要执行多条sql语句对数据库进行多次访问,从而加快了数据的处理速度。并且Gorm框架可以根据设计好的Model完成返回数据的封装,并不需要自己对数据进行再次封装。

技术详述

本次团队项目中我们获取评论数据时,不仅需要返回评论的相关信息,还要返回评论的作者的相关信息。如果不用Gorm的多表查询,则需要我们对每一条数据进行一次额外的查询和封装操作。下面是Gorm框架实现多表查询的具体步骤。

1. Model设计
评论和用户是一对多的关系,即一个评论属于一个用户,一个用户可以发布多条评论。

//评论
type Comment struct {
	ID          int64     `gorm:"column:ID;primaryKey"`
	UserID      string    `gorm:"column:userID"`
	Content     string    `gorm:"column:content"`
	CommentNum  int64     `gorm:"column:CommentNum"`
	TargetPost  int64     `gorm:"column:targetPost"`
	PublishTime time.Time `gorm:"column:publishTime"`
	State       int64     `gorm:"column:state"`
	Author      User      `gorm:"foreignKey:UserID"`
}

//用户
type User struct {
	ID            int64 `gorm:"column:ID;primaryKey"`
	Account       string
	Password      string
	PhoneNumber   string `gorm:"column:phoneNumber"`
	NickName      string `gorm:"column:nickName"`
	Major         string
	AvatarUrl     string `gorm:"column:avatarUrl"`
	Sex           string
	Area          string
	Year          int64
	TargetCollege string `gorm:"column:targetCollege"`
	TargetMajor   string `gorm:"column:targetMajor"`
	Slogan        string
	Balance       int64
	College       string
	State         int64     `gorm:"column:state"`
	RegisterTime  time.Time `gorm:"column:registerTime"`
}

可以看到在评论中我添加了User类型的Author字段,还在后面指定了外键是UserID,这样Gorm框架就可以根据UserID进行连表查询,并且不需要额外进行封装工作。

2. SQL语句设计

func SelectSingleCommentByCondition(db *gorm.DB, where map[string]interface{}) (Comment, int64, error) {
	var count int64 = 0
	var comment Comment
	err := db.Joins("Author").Where(where).First(&comment).Count(&count).Error
	if count == 0 {
		return comment, 0, errors.New("查询的记录不存在")
	}
	return comment, count, err
}

关键点在于要利用Joins()函数来选择连接查询的表,并且这里的函数参数要根据刚刚的Model设计中的命名来选择,比如在Comment中我们要查询的是Author字段,就传入“Author”。

3. 结果测试
测试函数:

package selectComment

import (
	fybDatabase "FybBackend/database"
	"FybBackend/routers/v1/backend/token"
	"FybBackend/routers/v1/exceptionHandler"
	"github.com/gin-gonic/gin"
	"github.com/hashicorp/go-multierror"
	"gorm.io/gorm"
)

func SelectCommentById(e *gin.Engine, db *gorm.DB) {
	e.GET("/v1/backend/comment/searchById", func(context *gin.Context) {
		if err := token.JwtVerify(context); err != nil {
			context.JSON(403, gin.H{
				"code":    403,
				"message": err.Error(),
			})
			return
		}

		var result *multierror.Error
		mp := make(map[string]interface{})
		mp["comment.id"] = context.DefaultQuery("id", "")
		post, _, err1 := fybDatabase.SelectSingleCommentByCondition(db, mp)
		result = multierror.Append(result, err1)

		code, msg := exceptionHandler.Handle(result)
		if code == 200 {
			context.JSON(code, gin.H{
				"code":    code,
				"message": "请求成功",
				"data":    post,
			})
		} else {
			context.JSON(code, gin.H{
				"code":    code,
				"message": msg,
			})
		}
	})
}

利用Postman对接口进行测试,返回结果如下:
在这里插入图片描述
可以看到测试函数中没有进行额外的数据封装,返回的结果结构就是按照Model设计中那样返回。

遇到的问题和解决过程

  • 问题:sql语句中如何确定是使用left join、right join 还是 inner join

通俗来说,对于表A和表B,left join返回包括表A中的所有记录和表B中联结字段相等的记录;right join返回包括表B中的所有记录和表A中联结字段相等的记录;inner join只返回两个表中联结字段相等的行。下面用一张图来直观的表示:
在这里插入图片描述
这里我们要查询的是评论的数据,因此选择left join。那么写的查询函数为什么用的是Joins()函数呢?通过查询Gorm框架的源代码我们可以发现,Joins函数就是使用了left join。
在这里插入图片描述

总结

  • 经过这次对Gorm框架的多表联合查询的学习,进一步加强了我对Gorm框架的掌握程度,对数据库的学习有了更深的理解。
  • 作为后端开发人员,需要进一步对数据库的使用进行研究和学习,不断提高自身的技术能力,多多阅读官方文档和他人的博客,学习他们的方法和技巧。

参考文献

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值