GO语言工程实践课后作业 | 豆包MarsCode AI刷题

39 阅读2分钟

社区话题页面

需求用例

主要就是浏览消费者用户,有 2 个对应的结构体,一个是 Post,一个是 Topic

ER图

  • 话题 Topic

    • id
    • title
    • content
    • reate_time
  • 帖子

    • id
    • Topic_id
    • content
    • create_time

分层结构

  • 数据层:数据 Model,外部数据的增删改查
  • 逻辑层:业务 Entity,处理核心业务逻辑输出
  • 视图层:视图 view,处理和外部的交互逻辑

组件

Gin

Go Mod

go mod init

go get gopkg.in/gin-gonic/gin.v1@v1.3.0

go get -u github.com/gin-gonic/gin

具体实现——数据层

  1. 数据模型 Post

Post 结构体定义了 post 表的数据模型。它包含了数据库表中的字段映射,通过 GORM 的标签(gorm:"column:xxx")将结构体的字段与数据库表的列关联起来。

type Post struct {
	Id         int64     `gorm:"column:id"`
	ParentId   int64     `gorm:"parent_id"`
	UserId     int64     `gorm:"column:user_id"`
	Content    string    `gorm:"column:content"`
	DiggCount  int32     `gorm:"column:digg_count"`
	CreateTime time.Time `gorm:"column:create_time"`
}

func (Post) TableName() string {
	return "post"
}
  • Post 结构体中的字段(如 Id, ParentId, UserId, Content, 等)对应数据库表 post 中的字段。
  • TableName() 方法告诉 GORM 使用 post 作为表名。
  1. PostDao 数据访问对象

PostDao 是数据访问对象(DAO),它提供了操作 post 表的数据库方法。PostDao 包含了与 post 数据库表的交互方法,如查询和插入操作。

type PostDao struct{}
  • PostDao 结构体作为一个容器,持有操作 post 数据表的逻辑方法。
  1. 单例模式:NewTopicDaoInstance

为了确保 PostDao 只会实例化一次,代码使用了 Go 的 sync.Once 实现了一个单例模式。sync.Once 保证了 postDao 只会被初始化一次。

var postDao *PostDao
var postDao sync.Once

func NewTopicDaoInstance() *PostDao {
	postOnce.Do(
		func() {
			postDao = &PostDao{}
		})
	return postDao
}
  • sync.Once.Do() 确保了 postDao 只会在首次调用时被初始化。之后的调用会直接返回已经初始化的 postDao 实例。
  1. 数据库操作方法

这些方法负责执行具体的数据库操作,如查询单个帖子、根据父帖子查询所有子帖、以及创建新帖子。

QueryPostById 方法

查询指定 id 的帖子。

func (*PostDao) QueryPostById(id int64) (*Post, error) {
	var post Post
	err := db.Where("id = ?", id).Find(&post).Error
	if err != nil {
		util.Logger.Error("find post by id err:" + err.Error())
		return nil, err
	}
}
  • 该方法通过 GORM 的 Where 查询条件找到指定 id 的帖子,并将其返回。如果查询失败,打印错误信息并返回错误。

QueryPostByParentId 方法

查询指定 parentId 的所有帖子。

func (*PostDao) QueryPostByParentId(parentId int64) ([]*Post, error) {
	var posts []*Post
	err := db.Where("parent_id =?", parentId).Find(&posts).Error
	if err != nil {
		util.Logger.Error("find post by parent id err:" + err.Error())
		return nil, err
	}
	return posts, nil
}
  • 该方法通过 parent_id 查询所有子帖子,返回一个包含多个 Post 的切片。

CreatePost 方法

创建一个新的帖子。

func (*PostDao) CreatePost(post *Post) error {
	if err := db.Create(post).Error; err != nil {
		util.Logger.Error("create post err:" + err.Error())
		return err
	}
	return nil
}
  • 该方法将一个新的 Post 记录插入到数据库中。如果插入失败,返回错误。