go-zero(三) 数据库操作
go-zero 数据库操作
在本篇文章中,我们将实现一个用户注册和登录的服务。我们将为此构建一个简单而高效的 API,包括请求参数和响应参数的定义。
一、Mysql连接
1. 创建数据库和表
在 MySQL 中创建名为 test_zero
的数据库,并创建`user 表
CREATE TABLE `users` (`id` BIGINT NOT NULL AUTO_INCREMENT,`username` VARCHAR(50) NOT NULL COLLATE 'utf8_general_ci',`password` VARCHAR(255) NOT NULL COLLATE 'utf8_general_ci',`created_at` TIMESTAMP NULL DEFAULT (CURRENT_TIMESTAMP),PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `username` (`username`) USING BTREE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
可以看到username
字段被我设置了唯一性即UNIQUE
,这里先解释一下,使用goctl
生成model代码的时候,它会自动帮我们生成增删改查
等方法。
如果字段设置了唯一性,它会自动生成通过这个字段查找数据的方法,后续我希望通过username
去查询和修改用户数据,所以这里设置了一下。
2. 创建API文件
接下来我们根据这个表,创建user.api
文件,
syntax = "v1"type (// 定义注册接口的 json 请求体RegisterRequest {//请求体定义了 Username 和Password 字段, 并且都设置了不能为空Username string `json:"username" validate:"required"` Password string `json:"password" validate:"required"`}// 定义注册接口的 json 响应体RegisterResponse {//响应体 定义类一个Message 用来返回结果Message string `json:"message"`}
)type (// 定义登录接口的 json 请求体LoginRequest {Username string `json:"username" validate:"required"`Password string `json:"password" validate:"required"`}// 定义登录接口的 json 响应体LoginResponse {//正常的业务逻辑,用户登录后会产生一个token,用来记录登录信息Token string `json:"token"`}
)@server (group: user // 生成代码时都会被放到 user 目录下prefix: /v1 //定义路由前缀为 "/v1"
)// 定义 HTTP 服务
// 微服务名称为 user-api,生成的代码目录和配置文件将和 user 值相关
service user-api {// 定义用户注册接口//定义 http.HandleFunc 转换的 go 文件名称及方法@handler RegisterHandler// 请求方法为 post// 路由为 /register // 请求体为 RegisterRequest// 响应体为 RegisterResponse,响应体必须有 returns 关键字修饰post /register (RegisterRequest) returns (RegisterResponse)//用户登录@handler LoginHandlerpost /login (LoginRequest) returns (LoginResponse)
}
这个 API 的结构可以通过注释清晰地理解。在下面这段代码中,我们可以看到请求参数和响应参数之间通过 returns
进行修饰:
post /register (RegisterRequest) returns (RegisterResponse)
需要注意的是,请求参数
和响应参数
并不总是必需的。
例如,在更新数据时,我们可以省略响应体,只保留请求参数:
post /update (UpdateUserInfoReq)
同样,当我们通过 token 获取数据时,也可以省略请求体,而只定义响应参数:
get /getinfo returns (UserInfoResp)
这样的灵活性使得 API 定义更加简洁明了。
3. 生成服务代码和model代码
我们创建一个新的项目,目录设置为user
,使用goctl
通过user.api
生成项目代码:
goctl api go --api user.api --dir ./
下面我们就演示怎么使用goclt
以及sql
生成model
, 在刚刚生成的项目中,在internal
目录下创建一个modle
的文件夹,然后再这个文件夹下面创建user.sql
,把之前的sql语句粘贴进来,然后使用命令:
goctl model mysql ddl --src user.sql --dir ./
当你看到 Done. 输出则代表生成成功了,帮我们生成了下面3个文件。
$ tree
.
├── usermodel.go
├── usermodel_gen.go
└── vars.go
usermodel.go
: 定义数据库表的模型及其业务逻辑。usermodel_gen.go
: 自动生成的代码,包含数据库操作的实现。vars.go
: 全局变量和配置的定义,供各个模块使用。
4.查看model代码
现在我们来具体看下goctl
帮我们生成的model代码,我们先看下usersmodel.go
文件,
它帮我们定义了NewUsersModel
用来返回user表模型
// NewUsersModel returns a model for the database table.
//NewUsersModel 返回数据库表的模型
func NewUsersModel(conn sqlx.SqlConn) UsersModel {return &customUsersModel{defaultUsersModel: newUsersModel(conn),}
}
接着看下usersmodel_gen.go
文件:
帮我们根据数据库自动生成了数据模型
Users struct {Id int64 `db:"id"`Username string `db:"username"`Password string `db:"password"`CreatedAt time.Time `db:"created_at"`}
给usersModel定义了基本的增删改查的接口
usersModel interface {Insert(ctx context.Context, data *Users) (sql.Result, error)FindOne(ctx context.Context, id int64) (*Users, error)FindOneByUsername(ctx context.Context, username string) (*Users, error)Update(ctx context.Context, data *Users) errorDelete(ctx context.Context, id int64) error
}
5.链接数据库
go-zero 提供了一个强大的 sqlx 工具,用于操作数据库。 所有 SQL 相关操作的包在 github.com/zeromicro/go-zero/core/stores/sqlx
在使用 go-zero 框架与数据库交互时,通常会遵循一系列的步骤和逻辑,下面是调用数据库的典型顺序和逻辑:
增加数据库连接配置
打开 etc\user-api.yaml
文件,增加 MySQL 连接字符串:
#定义了一个名为MysqlDB的结构体,并有一个名为DbSource的字符串。
MysqlDB:# 字符串请根据实际配置环境更改DbSource: "root:root@tcp(127.0.0.1:3306)/test_zero"
设置结构体,用来解析配置文件
现在我们需要把这个MysqlDB
这个字段映射到 go-zero的结构体中,打开internal/config/config.go
文件,把代码修改为以下:
type Config struct {rest.RestConfMysqlDb struct{DbSource string `json:"DbSource"`}
}
我们之前提到过,Config 结构体中的字段与 YAML 文件中的字段可以不区分大小写,但必须保持一致,否则会导致解析错误。如果希望使用不同的名称,可以通过 json:
标签指定 YAML 文件中对应的字段名。
把数据库连接注册到服务上下文
go-zero提供了一个快捷的方式可以创建 Mysql 链接,接着我们就可以使用这个连接进行各种数据库操作:
func NewMysql(datasource string, opts ...SqlOption) SqlConn
我们先使用sqlx.NewMysql(c.MysqlDb.DbSource)
创建数据库连接,然后传给NewUsersModel
,初始化UserModel,打开internal/svc/servicecontext.go
文件,把代码修改为:
//ServiceContext 结构体用户封装服务的上下文信息,相当环境初始化type ServiceContext struct {Config config.Config //UserModel: 类型为 model.UsersModel,表示与用户相关的数据库模型//用于处理与用户相关的数据操作(如用户的创建、读取、更新和删除等)UserModel model.UsersModel
}
//NewServiceContext 是ServiceContext 的构造函数
//它接收配置参数并初始化 ServiceContext,确保服务可以访问所需的配置和数据模型
func NewServiceContext(c config.Config) *ServiceContext {return &ServiceContext{Config: c, //把配置信息注册到服务上下文//通过调用 model.NewUsersModel 函数对UserModel 进行初始化//sqlx.NewMysql 是数据库连接,链接字符串为config中的MysqlDb.DbSourceUserModel: model.NewUsersModel(sqlx.NewMysql(c.MysqlDb.DbSource)),}
}
sqlx.NewMysql
是 sqlx 包中的一个函数,通常用于创建一个新的 MySQL 数据库连接,我们可以看下它在go-zero中的代码, 就是传入datasource 字符串,然后返回SqlConn 数据库连接
func NewMysql(datasource string, opts ...SqlOption) SqlConn {opts = append([]SqlOption{withMysqlAcceptable()}, opts...)return NewSqlConn(mysqlDriverName, datasource, opts...)
}
二、CURD演示
1. 实现注册服务(查、赠)
现在我们开始实现注册逻辑
打开internal/logic/user/registerlogic.go
文件,修改代码如下:
func (l *RegisterLogic) Register(req *types.RegisterRequest) (resp *types.RegisterResponse, err error) {// todo: add your logic here and delete this lineuserModel := l.svcCtx.UserModel //从服务上下文获取UserModel //调用FindOneByUsername查询用户数据,判断用户是否已经注册//req.Username 从请求信息中获取 Usernameuser, _ := userModel.FindOneByUsername(l.ctx, req.Username)//如果username不为空说明已经注册if user != nil {//已经存在用户return nil, err}//插入新的数据_, err = userModel.Insert(l.ctx, &model.Users{Username: req.Username,Password: req.Password,CreatedAt: time.Now(),})if err != nil {// 注册失败return nil, err}//返回响应信息return &types.RegisterResponse{Message: "注册成功",}, nil
}
我们先运行程序,测试一下
2.实现登录服务 (查)
现在我们开始实现=登录逻辑
打开internal/logic/user/loginlogic.go
文件,修改代码如下:
func (l *LoginLogic) Login(req *types.LoginRequest) (resp *types.LoginResponse, err error) {// todo: add your logic here and delete this line//因为我们目前还没涉及到jwt鉴权,所以先把token当面message使用userModel := l.svcCtx.UserModeluser, _ := userModel.FindOneByUsername(l.ctx, req.Username)//查询username判断是否有数据if user != nil { //如果有数据,密码是否和数据库匹配if req.Password == user.Password {return &types.LoginResponse{Token: "登录成功",}, nil} else {return &types.LoginResponse{Token: "密码错误",}, nil}} else {return &types.LoginResponse{Token: "用户未注册",}, nil}}
运行项目
相关文章:

go-zero(三) 数据库操作
go-zero 数据库操作 在本篇文章中,我们将实现一个用户注册和登录的服务。我们将为此构建一个简单而高效的 API,包括请求参数和响应参数的定义。 一、Mysql连接 1. 创建数据库和表 在 MySQL 中创建名为 test_zero的数据库,并创建user 表 …...
SQL面试题——间隔连续问题
间隔连续问题 某游戏公司记录的用户每日登录数据如下 +----+----------+ | id| date| +----+----------+ |1001|2021-12-12| |1001|2021-12-13| |1001|2021-12-14| |1001|2021-12-16| |1001|2021-12-19| |1001|2021-12-20| |1002|2021-12-12| |1002|2021-12-16| |1002|…...

vim配置 --> 在创建的普通用户下
在目录/etc/ 下面,有个名为vimrc 的文件,这是系统中公共的vim配置文件对所有用户都有效 我们现在创建一个普通用户 dm 创建好以后,我们退出重新链接 再切换到普通用户下 再输入密码(是不显示的,输入完后,…...

(计算机毕设)基于SpringBoot+Vue的房屋租赁系统的设计与实现
博主可接毕设设计!!! 各种毕业设计源码只要是你有的题目我这里都有源码 摘 要 社会的发展和科学技术的进步,互联网技术越来越受欢迎。网络计算机的生活方式逐渐受到广大人民群众的喜爱,也逐渐进入了每个用户的使用。互…...

【含开题报告+文档+PPT+源码】基于SpringBoot的医院药房管理系统
开题报告 在科技迅速发展的今天,各行各业都在积极寻求与现代技术的融合,以提升自身的运营效率和竞争力。医疗行业作为关乎国计民生的关键领域,其信息化建设的步伐尤为迅速。医院药房作为医疗体系中的核心环节,其管理效率和服务质…...

基于SpringBoot的“数码论坛系统设计与实现”的设计与实现(源码+数据库+文档+PPT)
基于SpringBoot的“数码论坛系统设计与实现”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统总体结构图 系统首页界面图 数码板…...

Linux-第2集-打包压缩 zip、tar WindowsLinux互传
欢迎来到Linux第2集,这一集我会非常详细的说明如何在Linux上进行打包压缩操作,以及解压解包 还有最最重要的压缩包的网络传输 毕竟打包压缩不是目的,把文件最终传到指定位置才是目的 由于打包压缩分开讲没有意义,并且它们俩本来…...

项目进度计划表:详细的甘特图的制作步骤
甘特图(Gantt chart),又称为横道图、条状图(Bar chart),是一种用于管理时间和任务活动的工具。 甘特图由亨利劳伦斯甘特(Henry Laurence Gantt)发明,是一种通过条状图来…...

Cargo Rust 的包管理器
Cargo->Rust 的包管理器 Cargi简介Cargo 的主要功能1. 创建项目2. 管理依赖3. 构建项目4. 运行项目5. 测试代码6. 检查代码7. 生成文档8. 发布和分享包 Cargo 的核心文件1. Cargo.toml2. Cargo.lock **Cargo 的生态系统** 常用命令总结Hello, Cargo! 示例 Cargi简介 Cargo …...

【Rust 编程语言工具】rustup-init.exe 安装与使用指南
rustup-init.exe 是用于安装和管理 Rust 编程语言工具链的 Windows 可执行文件。Rust 是一种系统级编程语言,旨在提供安全、并发和高性能的功能。rustup-init.exe 是官方提供的安装器,用于将 Rust 安装到 Windows 操作系统中,并配置相关环境。…...

集群聊天服务器(12)nginx负载均衡器
目录 负载均衡器nginx负载均衡器优势 如何解决集群聊天服务器跨服务器通信问题?nginx的TCP负载均衡配置nginx配置 负载均衡器 目前最多只能支持2w台客户机进行同时聊天 所以要引入集群,多服务器。 但是客户连哪一台服务器呢?客户并不知道哪一…...

数据挖掘英语及概念
分类 classify 上涨或跌 回归 regression 描述具体数值 分类模型评估 1.混淆(误差)矩阵 confusion matrix 2.ROC曲线 receiver operating characteristic curve 接收者操作特征曲线 3.AUC面积 area under curve ROC曲线下与坐标轴围成的面积&#x…...
springboot第82集:消息队列kafka,kafka-map
官网下载链接:https://kafka.[apache].org/downloads 我下载的是[Scala]2.12 - kafka_2.12-3.1.0.tgz kafka只需要解压下载的压缩包就行了,我这里解压的路径是D:\kafka_2.12-3.1.0,kafka的运行需要依赖zookeeper,当前版本已经内置…...

sql server查看当前正在执行的sql
#统计某类sql执行次数,并按总体cpu消耗时间降序排序 with a as ( select er.session_id,db_name(er.database_id) as DBNAME,sy.last_batch AS 最后执行时间, er.cpu_time ,er.total_elapsed_time/1000 as sum_elapsed_time_s, CAST(csql.text AS varchar(8000)) A…...

STM32设计学生宿舍监测控制系统-分享
目录 前言 一、本设计主要实现哪些很“开门”功能? 二、电路设计原理图 电路图采用Altium Designer进行设计: 三、实物设计图 四、程序源代码设计 五、获取资料内容 前言 本项目旨在利用STM32单片机为核心,结合传感器技术、无线通信技…...
HAproxy 详解
一、基本概念 1.1 什么是 HAproxy? HAproxy(High Availability Proxy)是一个开源的高性能负载均衡器和反向代理服务器,它主要用于在网络上分发流量,以提高网站或应用程序的可用性和性能。HAproxy 可以处理大量的并发…...

间接采购管理:主要挑战与实战策略
间接采购支出会悄然消耗掉企业的现金流,即使是管理完善的公司也难以避免。这是因为间接支出不直接关联特定客户、产品或项目,使采购人员难以跟踪。但正确管理间接支出能为企业带来显著收益——前提是要有合适的工具。本文将分享管理间接支出的关键信息与…...
2411rust,正与整128
原文 长期以来,Rust在x86-32和x86-64架构上128位整数的对齐与C语言不一致.最近已解决此问题,但该修复带来了一些值得注意的效果. 作为用户,除非如下,否则不用担心: 1,假设i128/u128对齐,而不是用align_of 2,忽略improper_ctypes*检查,并在FFI中使用这些类. 除x86-32和x86-64…...

将 HTML 转换为 JSX:JSX 和 JSX 规则
JSX 是 JavaScript 的语法扩展。您可以在 JavaScript 文件中编写 HTML 格式。 它基于 Web、Html、Css 和 JavaScript。Web 开发人员将页面内容分别编写为 Html 文件,将设计编写为 Css 文件,将逻辑编写为 JavaScript 文件。 须知 : JSX 是一个…...

将 FastAPI 部署到生产服务器(一套 全)
将 FastAPI 部署到生产服务器(全) 文章目录 将 FastAPI 部署到生产服务器(全)一、前言二、Fastapi项目 生产环境配置1. 准备环境2. 编写 FastAPI 应用3. 使用 Uvicorn 运行应用4. 配置生产级服务器 Gunicorn4.1 配置 Gunicorn 和 …...

Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...
比特币:固若金汤的数字堡垒与它的四道防线
第一道防线:机密信函——无法破解的哈希加密 将每一笔比特币交易比作一封在堡垒内部传递的机密信函。 解释“哈希”(Hashing)就是一种军事级的加密术(SHA-256),能将信函内容(交易细节…...
后端下载限速(redis记录实时并发,bucket4j动态限速)
✅ 使用 Redis 记录 所有用户的实时并发下载数✅ 使用 Bucket4j 实现 全局下载速率限制(动态)✅ 支持 动态调整限速策略✅ 下载接口安全、稳定、可监控 🧩 整体架构概览 模块功能Redis存储全局并发数和带宽令牌桶状态Bucket4j Redis分布式限…...