GoFrame新手实战之个人博客(四)

引言:

在完成了对管理员登录功能的简单实现后,接下来围绕文章和标签两张表的crud进行操作。


一:文章表的crud

首先完善新增文章操作
controller层

仿照参考文档中的代码,为/controller/article/article_v1_article_create.go编写代码

func (c *ControllerV1) ArticleCreate(ctx context.Context, req *v1.ArticleCreateReq) (res *v1.ArticleCreateRes, err error) {
	err = service.Article().Create(ctx, model.ArticleCreateInput{
		Content:  req.Content,
		Layout:   req.Layout,
		PostName: req.PostName,
		Tags:     req.Tags,
		Title:    req.Title,
		TagsId:   req.TagsId,
	})
	return
}

解决报红的三个地方,在model层中创建article.go,定义ArticleCreateInput结构体,目的是为了定义统一的入参结构,具体如何理解个人参考的是这篇文章GoFrame V2真香,我是Get到了高内聚低耦合的点,你呢?_Go_王中阳Go_InfoQ写作社区

ArticleCreateInput如下

type ArticleCreateInput struct {
	Content  string
	Layout   string
	PostName string
	Tags     string
	Title    string
	Post     int
	TagsId   string
}

接下来因为要使用logic来生成service接口,所以先编写logic层的代码

logic层

在/logic/article下创建article.go

type (
	sArticle struct {
	}
)

func init() {
	service.RegisterArticle(New())
}
func New() service.IArticle { return &sArticle{} }
func (s *sArticle) Create(ctx context.Context, in model.ArticleCreateInput) (err error) {
	if in.Title == "" {
		return err
	}
	if in.Content == "" {
		return err
	}
	return dao.Article.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		_, err := dao.Article.Ctx(ctx).Data(do.Article{
			Content:  in.Content,
			Layout:   in.Layout,
			Post:     in.Post,
			PostName: in.PostName,
			TagsId:   in.TagsId,
			Title:    in.Title,
		}).Insert()
		return err
	})
}

由于我goLand配置了官方给的自动配置模块规范-gen service - GoFrame (ZH)-Latest - GoFrame官网 - 类似PHP-Laravel, Java-SpringBoot的Go企业级开发框架

因此编写完成后无需手动输入gf gen service。

后来在测试前发现了数据库的create_time和update_time自己设置了不能为空,于是在插入语句中新增两句

            CreateTime: gtime.New(time.Now()),
			UpdateTime: gtime.New(time.Now()),

检查数据库,数据库中也成功插入数据

这样一个基本的新增操作就完成了

删除数据

这里采用逻辑删除,也就是软删除,所以本质上也就是update。以deleteTime是否为空作为判断是否删除的标准.

步骤和上面的操作一样

先检查api接口
package v1

import "github.com/gogf/gf/v2/frame/g"

type ArticleDeleteReq struct {
	g.Meta `path:"/article/delete" tags:"Article" method:"post" summary:"删除文章"`
	Id     int `p:"id" v:"required#文章ID不能为空" dc:"文章ID"`
}
type ArticleDeleteRes struct {
}
然后在controller对应的包下编写代码
package article

import (
	"context"
	"demo-blog/internal/model"
	"demo-blog/internal/service"

	"demo-blog/api/article/v1"
)

func (c *ControllerV1) ArticleDelete(ctx context.Context, req *v1.ArticleDeleteReq) (res *v1.ArticleDeleteRes, err error) {
	err = service.Article().Delete(ctx, model.ArticleDeleteInput{
		Id: req.Id,
	})
	return
}
在model层创建ArticleDeleteInput结构体
type ArticleDeleteInput struct {
	Id int
}
最后在logic层的article/article.go中编写

Transaction是添加事务管理

func (s *sArticle) Delete(ctx context.Context, in model.ArticleDeleteInput) (err error) {
	return dao.Article.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		_, err := dao.Article.Ctx(ctx).Where("id", in.Id).Update(do.Article{
			DeleteTime: gtime.New(time.Now()),//为输入id对应的那条数据更新delete_time
		})
		return err
	})
}

在之后的所有查询里,都要添加上判断delete_time是否为空的条件。比较麻烦,但是goframe有解决的方案:ORM链式操作-时间维护 - GoFrame (ZH)-Latest - GoFrame官网 - 类似PHP-Laravel, Java-SpringBoot的Go企业级开发框架

只不过只能在它的链式操作中使用,并且数据库要包含create_at,update_at,delete_at任意或多个字段时才启用。

现在重新运行一下项目

测试接口

别忘了在业务层或控制层对输入的内容进行判断,确保输入数据符合要求。

可以看到成功的为这条字段更新了删除时间,删除操作也完成了。

查询操作

默认写分页查询。

分页查询可参考官方文档ORM查询-ScanAndCount - GoFrame (ZH)-Latest - GoFrame官网 - 类似PHP-Laravel, Java-SpringBoot的Go企业级开发框架

总结:

api层用于处理接收的参数

        model层用于控制传入的数据标准

        controller层将得到的数据传入业务层

        logic层处理具体的业务逻辑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值