kratos 框架编写一个小demo

news/2025/10/24 6:07:34/文章来源:https://www.cnblogs.com/rush-peng/p/19161966

保证本机安装 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.mzph.cn/news/944804.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[MS-DOS] DOS_6.22_Users_Manual_1994.pdf

http://www.bitsavers.org/pdf/microsoft/msdos_6.22/DOS_6.22_Users_Manual_1994.pdf Microsoft book: http://www.bitsavers.org/pdf/microsoft

主席树(可持久化线段树)

主席树(可持久化线段树) 以 \(\mathcal O(N\log N)\) 的时间复杂度建树、查询、修改。 struct PresidentTree {static constexpr int N = 2e5 + 10;int cntNodes, root[N];struct node {int l, r;int cnt;} tr[4 * N…

2025 CSP 赛前复习笔记

施工中。。。 计数 基础知识 容斥原理 子集反演 二项式反演 卡特兰数 / 反射容斥 斯特林数 / 斯特林反演 矩阵树定理 * BEST定理 * Prufer序列 * (* : NOIP 用不到,鸽一下) 基础知识 对称恒等式 \[\binom{n}{k}=\bino…

Borland Turbo products

https://bitsavers.org/bits/Borland/https://winworldpc.com/search?vendor=Borland

港科语义地图-低带宽场景下的多机器人地图对齐与共享定位提供了通用基石 - MKT

港科语义地图-低带宽场景下的多机器人地图对齐与共享定位提供了通用基石 Generalizable and Efficient Scene Graph Registration【IEEE TRO】地址:https://arxiv.org/pdf/2504.14440地址:https://arxiv.org/pdf/250…

Spring Boot 整合 MiniMax 与 CosyVoice 语音合成服务实践指南

在有声内容创作领域,如智能配音、播客生成等场景,MiniMax 和 CosyVoice 提供的高拟真 TTS 技术展现出比传统方案更优的语音表现力。本文将详细介绍如何在 Spring Boot 应用中通过 UnifiedTTS 标准化接口实现这两项技…

港科轻量化地图 - MKT

港科轻量化地图https://mp.weixin.qq.com/s/q0DQ2xJ3JCAEAwh8YTsWWw?poc_token=HI1v-mijfX0vzPhPnzStzS7Qli4EesEHCe-LmzsOSEPT:Standard-Definition Map Enhanced Scene Perception and Topology Reasoning for Aut…

PandaCoder:致敬MyBatis Log Plugin,但我们做得更极致!

PandaCoder:致敬MyBatis Log Plugin,但我们做得更极致! 各位开发者朋友,大家好! 今天给大家推荐一款改变开发体验的神器:PandaCoder 先问几个灵魂拷问 🤔 场景1:看到一条慢SQL,你能立刻知道是哪个API接口触发…

251024

251024https://www.bilibili.com/video/BV1aYsPzCEDW/?spm_id_from=333.1007.tianma.2-2-5.click&vd_source=1938d9661fe31c9bbeeed5a854b862eb

Python---学习

最近要做一些项目,需要用到Python,并不陌生,自己就是程序员,还是重新学习一下。 学习视频:https://www.bilibili.com/video/BV13e411172J/记录学习知识点: 1、注释:#print(你好); # 输出您好 三个逗号,就是多行…

[DOS] Borland Turbo Assembler learning 8086/real-mode assembly

on DOS, is using borland turbo assembler to learn Assembly still meaningful to understanding todays Intel CPU architecture?Absolutely, but let me be very precise and pedantic here: it’s meaningful, b…

搭建x86汇编语言学习环境

没想到最后居然还是得用最原始的DOS 详细参考这里: https://blog.csdn.net/sxhelijian/article/details/54845039 资料下载见这里: https://github.com/ChHsiching/8086-Assembly-DevEnv非常合适——如果你的目标是系…

CF1401B Ternary Sequence

CF1401B Ternary Sequence题目描述 给定两个序列 \(a_1, a_2, \dots, a_n\) 和 \(b_1, b_2, \dots, b_n\),每个序列中的元素都是 \(0\), \(1\) 或 \(2\)。序列 \(a\) 中 \(0\), \(1\), \(2\) 的个数分别为 \(x_1\), …

离在线SDK配置

参数选项与协议命令关联表 参数类别 参数选项 配置值/说明 关联的命令 (cmd_type) 命令说明/参数识别参数 识别灵敏度 中 SET_VAD_SENSITIVITY (0x010A) 设置VAD灵敏度算法参数 AEC打断类型 唤醒词和命令打断 (协议层面…

傅立叶,程心和路明泽

再此记录一下恋爱的日记 2025/10/14 傅立叶因为心碎综合征休眠了。 全天都是程心和路明泽。

SpringBoot自动配置

SpringBoot 自动配置的原理是什么? Spring在启动的时候会自动扫描外部jar包中的META-INF\spring.factories,将文件中的配置类型信息加载到Spring容器,并且执行类中定义的操作。对于外部的jar包来说,只要遵循Spring…

AI元人文构想与余溪诗学空间:一场从诗意本源向智能未来的远征

AI元人文构想与余溪诗学空间:一场从诗意本源向智能未来的远征 在技术理性日益主导的今天,AI元人文构想以其对价值共生、人机协同的深刻思考独树一帜。然而,这一构想的精神内核与思想方法,并非源于纯粹的技术哲学推…

搞定三大PLC通讯:倍福与西门子、欧姆龙与西门子数据互通实战

EtherCAT与PROFINET的双主站通信网关 当前,智能产线普遍混合使用了EtherCAT和PROFINET两种主流技术,但要整合它们却非常困难:当两类设备需要协同工作时,如何实现它们之间高效、可靠的数据互通,就成了推动智能制造…

牛客2025秋季算法编程训练联赛2-(基础组提升组)

A.做游戏原题链接 解题思路尽可能多的使牛牛获胜,那么出石头,剪刀,布三种都取获胜的最大可能,对于石头:牛牛出的石头数量与牛可乐出的剪刀数量,剪刀和布亦然 note:注意c++开 long longAC code void solve(){ll a…