当前位置: 首页 > news >正文

kratos 框架编写一个小demo

保证本机安装 kratos 的前提下, 创建一个模板

kratos new review-service -r https://gitee.com/go-kratos/kratos-layout.git

.gitignore中,添加如下一行,就可以把这个仓库,用自己的git托管了。(因为.pb.go文件,其实可以使用 make 生成,个人感觉,不需要使用git托管)

*.pb.go

新添加 proto 文件,到 api ,并根据 api 文件,创建对应的 service文件

kratos proto add api/review/review.proto
make api
kratos proto server api/review/review.proto -t internal/service

结果如下图所示:
image

数据库

设计数据库并使用 ORM 自动生成数据库

在生产环境,一般是使用 sql 文件在数据库跑;本文比较简单,直接用 orm 生成

  1. 创建目录 internal/model/mysqlmodel,代码如下:
package mysqlmodelimport ("time""gorm.io/gorm"
)type ReviewInfo struct {ID uint `gorm:"primaryKey,autoIncrement"`// 默认可以为空,非空,要显示设置;UserID uint `gorm:"comment:创建方表示;not null"`// varchar(512) 这里的 512是字符数,不是字节数,这里能存 512个汉字Content        string         `gorm:"type:varchar(512);comment:评论内容;not null"`Score          uint8          `gorm:"type:tinyint(4);comment:评分;not null"`ShopScore      uint8          `gorm:"type:tinyint(4);comment:商家评分;not null"`LogisticsScore uint8          `gorm:"type:tinyint(4);comment:物流评分;not null"`HavePicture    bool           `gorm:"not null;comment:是否有图片,默认没有,有的话,去ReviewImage表中查询"`Status         uint8          `gorm:"comment:审核状态,1:待审核,2:已审核,3:已拒绝;not null;default:0"`OptIdea        string         `gorm:"type:varchar(216);comment:审核建议,如果拒绝,写拒绝的原因;not null"`CreatedAt      time.Time      `gorm:"comment:创建时间,自动生成"`UpdatedAt      time.Time      `gorm:"comment:更新时间,自动生成"`DeletedAt      gorm.DeletedAt `gorm:"index;comment:逻辑删除"`
}// 用于执行 mino中的 url
type ReviewImage struct {ID uint `gorm:"primaryKey,autoIncrement"`// 评论和评论回复图片都要存储,所以这里要区分// 在查询过程中,如果差图片,肯定要指定实体类型,所有创建联合索引,更合理// gorm中,两个字段使用同一个索引名将创建复合索引// 优先级 priority 定义,在查询过程中,先根据实体类型查询,再根据实体ID查询EntityType uint8          `gorm:"index:idx_type_review_id,priority:1;type:tinyint(4);comment:实体类型,1:订单,2:评价"`EntityID   uint           `gorm:"index:idx_type_review_id,priority:2;comment:评论ID,用于关联ReviewInfo,创建索引"`URL        string         `gorm:"type:varchar(256);comment:图片URL"`CreatedAt  time.Time      `gorm:"comment:创建时间,自动生成"`UpdatedAt  time.Time      `gorm:"comment:更新时间,自动生成"`DeletedAt  gorm.DeletedAt `gorm:"index;comment:逻辑删除"`
}// 回复评论的列表
type ReviewReployInfo struct {ID        uint           `gorm:"primaryKey,autoIncrement"`ReviewID  uint           `gorm:"index:idx_review_id;comment:评论ID,用于关联ReviewInfo,创建索引"`CreatedAt time.Time      `gorm:"comment:创建时间,自动生成"`UpdatedAt time.Time      `gorm:"comment:更新时间,自动生成"`DeletedAt gorm.DeletedAt `gorm:"index;comment:逻辑删除"`
}

针对上表,为何如此设计,有几个问题,需要考虑

1. 为何目录为 internal/model/mysqlmodel ?

模型结构体,应该定义在 model 中,但是需要区分 esmysql两种实体。如果直接叫 internal/model/mysql,根据go语言规范,package也要叫 mysql会和 data 层面的大量关键字冲突,自己写的代码,还能起个别名,但本文用的gen会自动生成文档,这个不好起别名,故包名 myqlmodel

2. 范式问题

因为 review 表中的图片,是存放在 ReviewImage 中的,而且 ReviewImage 表中的数据,会很多。那么是否可以在reviewInfo表中,冗余一个imageId组成的数组,直接在reviewImage表根据主键查询呢? 答案是不行,这明显不符合第一范式,会给后续的增删改查,都买下了大雷,至于考虑的提高性能的问题,大哥,考虑的有点多了。不要给自己找麻烦,才是正经。性能考虑是dba的事。

3. 组合索引问题

因为 评论回复评论,都存在 reviewImage中了,所以查找之前,一定会声明类型(是 review 还是 reviewReply?)。所以这里要组合索引。再想想,他是否是唯一索引呢?(答案:不是)

4. gorm的使用技巧

具体看看注释吧,或者看看 gorm 的官方文档。https://gorm.io/zh_CN/docs/index.html
数据库声明的 varchar(256) 字段,256 是指的字符不是字节,如果使用UTF8MB4字符集,表示能存 256 个汉字,如果超出了,可能会截断,也可能会报错。可以根据需要设置

5. 模型定义好了,怎么链接数据库,自动迁移呢?

随便创建个文件空文件夹,起package名为main,用下面代码,跑一下就行(一个go.mod 项目,可以有多个 main 函数,但是main函数必须在main包中)

package mainimport ("review-service/internal/model/mysqlmodel""gorm.io/driver/mysql""gorm.io/gen""gorm.io/gorm"
)func main() {// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情dsn := "root:123456@tcp(127.0.0.1:3306)/review?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})if err != nil {panic(err)}// Migrate the schemaif err := db.AutoMigrate(&mysqlmodel.ReviewInfo{}, &mysqlmodel.ReviewImage{}); err != nil {panic(err)}g := gen.NewGenerator(gen.Config{OutPath: "../query",Mode:    gen.WithoutContext | gen.WithDefaultQuery | gen.WithQueryInterface, // generate mode})g.UseDB(db) // reuse your gorm db// Generate basic type-safe DAO API for struct `model.User` following conventionsg.ApplyBasic(mysqlmodel.ReviewInfo{}, mysqlmodel.ReviewImage{}, mysqlmodel.ReviewReployInfo{})// Generate Type Safe API with Dynamic SQL defined on Querier interface for `model.User` and `model.Company`// g.ApplyInterface(func(Querier) {}, model.User{}, model.Company{})// Generate the codeg.Execute()
}

如果感觉,自动生成的代码,有点多。可以把 *.gen.go放到 .gitignore 中,在 makefile 文件中,加上如下一行,每次拉取后,都自动生成

autoMigrate:cd ./internal/model && go run generate_mysql.go

注意,我这里,是为了看代码的时候,防止太乱,所有就把所有自动生成的代码,过滤掉了。每次都重新生成。实际项目中不建议这么搞,避免版本变动,导致新生成的代码和老代码,对不上。。。

http://www.hskmm.com/?act=detail&tid=37746

相关文章:

  • [MS-DOS] DOS_6.22_Users_Manual_1994.pdf
  • 主席树(可持久化线段树)
  • 二维树状数组
  • 2025 CSP 赛前复习笔记
  • Borland Turbo products
  • 港科语义地图-低带宽场景下的多机器人地图对齐与共享定位提供了通用基石 - MKT
  • Spring Boot 整合 MiniMax 与 CosyVoice 语音合成服务实践指南
  • 港科轻量化地图 - MKT
  • PandaCoder:致敬MyBatis Log Plugin,但我们做得更极致!
  • CF1401B Ternary Sequence
  • [DOS] Borland Turbo Assembler learning 8086/real-mode assembly
  • 搭建x86汇编语言学习环境
  • 闭包
  • Python---学习
  • 离在线SDK配置
  • 傅立叶,程心和路明泽
  • SpringBoot自动配置
  • AI元人文构想与余溪诗学空间:一场从诗意本源向智能未来的远征
  • 状压DP
  • 搞定三大PLC通讯:倍福与西门子、欧姆龙与西门子数据互通实战
  • 实验p66
  • 牛客2025秋季算法编程训练联赛2-(基础组提升组)
  • 局域网共享一键通_v2.0.9.9
  • newDay15
  • 每日反思(2025_10_23)
  • 树链剖分/轻重链剖分
  • 如何降低信息化系统的构建成本? ——信息化系统省钱全攻略:从规划到运维的实用技巧
  • C#编程时winform程序登陆记住密码和自动登录功能,关于App.config的问题及解决方案
  • 2025.10.23总结
  • Day2超链接标签