文章目录
- 一、建表、插入测试数据、并生成对应的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 models
import "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 controller
import (
"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. 获取社区id
idStr := 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 logic
import (
"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 mysql
import (
"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).Error
if 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 = res
return
}
// GetCommunityDetailByID 根据ID查询社区详情
func GetCommunityDetailByID(id int64) (community *models.Community, err error) {
// 这里需要注意:尽管返回值中已经定义了community变量,但是并没有初始化,所以这里初始化它
//不初始化就使用会报错的
community = new(models.Community)
err = db.Where("community_id = ?", id).Find(community).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
err = ErrorInvalidID
}
}
return community, err
}
三、编译运行
可以看到,有四个社区标签可以选择了