文章目录
- 一、建表、插入测试数据、并生成对应的model
- 二、添加路由,以及controller、logic、dao三层分别实现对应代码
- 三、编译运行
登录之后,我们可以发表帖子,但是发表帖子之前,需要先选择一个频道,可以理解是社区分类或者标签分类。这个数据来源是从服务端获取的,本节我们就实现这个功能。
这是一个最基本的CRUD
功能,直接上代码吧,其中dev.yaml
和main.go
文件有改动是因为我想换为开发环境运行,这样可以直接调试以及观察控制台日志。
一、建表、插入测试数据、并生成对应的model
首先我们需要创建对应的表和model
,这里需要说明的是,我们将和DB
交互的model
以及和前端交互的model
使用了同一个,实际工作中一般是不会这样的。
- 和
DB
交互的model
,字段应该和表中的映射 - 和前端交互的
model
,一般是和前端对齐约定好的request
和response
结构
bluebell_community.sql
DROP TABLE IF EXISTS `community`;create table community
(id int auto_increment primary key,community_id int unsigned not null,community_name varchar(128) not null,introduction varchar(256) not null,create_time timestamp default CURRENT_TIMESTAMP not null,update_time timestamp default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP,constraint idx_community_id unique (community_id),constraint idx_community_name unique (community_name)
) collate = utf8mb4_general_ci;INSERT INTO community (id, community_id, community_name, introduction, create_time, update_time) VALUES (1, 1, 'Go', 'Golang', '2016-11-01 08:10:10', '2016-11-01 08:10:10');
INSERT INTO community (id, community_id, community_name, introduction, create_time, update_time) VALUES (2, 2, 'leetcode', '刷题刷题刷题', '2024-01-01 08:00:00', '2024-01-01 08:00:00');
INSERT INTO community (id, community_id, community_name, introduction, create_time, update_time) VALUES (3, 3, 'CS:GO', 'Rush B。。。', '2018-08-07 08:30:00', '2018-08-07 08:30:00');
INSERT INTO community (id, community_id, community_name, introduction, create_time, update_time) VALUES (4, 4, 'LOL', '欢迎来到英雄联盟!', '2016-01-01 08:00:00', '2016-01-01 08:00:00');select * from community;
使用如下地址https://www.qetool.com/sql_json_go/sql.html,直接将建表语句转为对应的结构体。
models/community.go
注意:因为前端读取社区id
是表中community_id
字段,name
是表中community_name
字段,所以下面这些字段的JSON tag
我做了修改。
- id:unique_id
- community_id:id
- community_name:name
package modelsimport "time"type Community struct {ID int64 `gorm:"column:id" db:"id" json:"unique_id" form:"id"`CommunityId int64 `gorm:"column:community_id" db:"community_id" json:"id" form:"community_id"`CommunityName string `gorm:"column:community_name" db:"community_name" json:"name" form:"community_name"`Introduction string `gorm:"column:introduction" db:"introduction" json:"introduction" form:"introduction"`CreateTime time.Time `gorm:"column:create_time" db:"create_time" json:"create_time" form:"create_time"`UpdateTime time.Time `gorm:"column:update_time" db:"update_time" json:"update_time" form:"update_time"`
}func (Community) TableName() string {return "community"
}
二、添加路由,以及controller、logic、dao三层分别实现对应代码
添加路由,获取社区列表、获取指定社区详情
router/route.go
v1.GET("/community", controller.CommunityHandler)
v1.GET("/community/:id", controller.CommunityDetailHandler)
添加两个handler
controller/community.go
package controllerimport ("bluebell/logic""strconv""github.com/gin-gonic/gin""go.uber.org/zap"
)// ---- 跟社区相关的 ----func CommunityHandler(c *gin.Context) {// 查询到所有的社区(community_id, community_name) 以列表的形式返回data, err := logic.GetCommunityList()if err != nil {zap.L().Error("logic.GetCommunityList() failed", zap.Error(err))ResponseError(c, CodeServerBusy) // 不轻易把服务端报错暴露给外面return}ResponseSuccess(c, data)
}// CommunityDetailHandler 社区分类详情
func CommunityDetailHandler(c *gin.Context) {// 1. 获取社区ididStr := c.Param("id") // 获取URL参数id, err := strconv.ParseInt(idStr, 10, 64)if err != nil {ResponseError(c, CodeInvalidParam)return}// 2. 根据id获取社区详情data, err := logic.GetCommunityDetail(id)if err != nil {zap.L().Error("logic.GetCommunityList() failed", zap.Error(err))ResponseError(c, CodeServerBusy) // 不轻易把服务端报错暴露给外面return}ResponseSuccess(c, data)
}
添加对应的logic
,尽管没有其他业务逻辑,就是简单的调用一下dao
层而已,但是为了规范,我们还是加了logic
这层,而不是让controller
层直接调用dao
层。
logic/community.go
package logicimport ("bluebell/dao/mysql""bluebell/models"
)func GetCommunityList() ([]*models.Community, error) {// 查数据库 查找到所有的community 并返回return mysql.GetCommunityList()
}func GetCommunityDetail(id int64) (*models.Community, error) {return mysql.GetCommunityDetailByID(id)
}
从DB
获取数据
dao/mysql/community.go
package mysqlimport ("bluebell/models""go.uber.org/zap""gorm.io/gorm"
)func GetCommunityList() (communityList []*models.Community, err error) {res := make([]*models.Community, 0)err = db.Model(models.Community{}).Find(&res).Errorif err != nil {zap.L().Error("server inner error")return nil, ErrorInnerServer}if len(res) == 0 {zap.L().Warn("there is no community in db")return res, nil}communityList = resreturn
}// GetCommunityDetailByID 根据ID查询社区详情
func GetCommunityDetailByID(id int64) (community *models.Community, err error) {// 这里需要注意:尽管返回值中已经定义了community变量,但是并没有初始化,所以这里初始化它//不初始化就使用会报错的community = new(models.Community)err = db.Where("community_id = ?", id).Find(community).Errorif err != nil {if err == gorm.ErrRecordNotFound {err = ErrorInvalidID}}return community, err
}
三、编译运行
可以看到,有四个社区标签可以选择了