在之前的几篇文章中,我们深入学习了Go-Zero框架的实战应用,包括模板定制化、API定义、抽奖算法设计等内容。本文将继续探索Go-Zero框架的实践技巧,并介绍一些与数据库操作相关的主题。
在现代应用程序开发中,对数据库的操作是非常常见且重要的一部分。Go-Zero框架提供了强大的数据库支持,使得我们可以轻松地进行数据库访问和操作。本文将重点介绍如何使用Go-Zero框架进行数据库的增删改查(CRUD)操作,并提供详细的示例代码和解释。
在本文中,我们将使用MySQL数据库作为示例,并结合Go-Zero框架的相关组件,如数据模型(Model)、事务处理、连接池等,来展示数据库操作的最佳实践。无论你是初学者还是有一定经验的开发者,本文都将为你提供有用的信息和技巧,帮助你更好地理解和应用Go-Zero框架中的数据库操作。
在阅读本文之前,请确保你已经按照前几篇文章中的说明进行了必要的准备工作,包括安装所需的工具和设置项目环境。同时,本文假设你已经具备一定的数据库基础知识,如表的创建、数据的插入和查询等。
通过学习本文,你将掌握以下内容:
我们鼓励你跟随示例代码,动手实践,并根据自己的需求进行定制和扩展。无论是为了学习Go-Zero的数据库操作,还是为了解决具体的业务问题,本文都将为你提供实用的指导和技巧。
祝你阅读愉快,并从中获得所需的知识和灵感!
本次实战我们是建立在(六)Go-Zero实战之docker开发环境部署 基础之上,如果没有学习过,可以点击跳转学习,然后再看本文哦!
本次实战采用的是docker部署,请提前准备好相关环境,关于docker环境的搭建在(六)Go-Zero实战之docker开发环境部署 中也有讲解,不了解小伙伴建议先行实战docker环境搭建哦!
mysql:
image: mysql/mysql-server:8.0.28
container_name: mysql
environment:
# 时区上海 - Time zone Shanghai (Change if needed)
TZ: Asia/Shanghai
# root 密码 - root password
MYSQL_ROOT_PASSWORD: xxxxxx #这里填上mysql的密码
ports:
- 33069:3306
volumes:
# 数据挂载 - Data mounting
- ./data/mysql/data:/var/lib/mysql
# 日志
command:
# 将mysql8.0默认密码策略 修改为 原先 策略 (mysql8.0对其默认策略做了更改 会导致密码无法匹配)
# Modify the Mysql 8.0 default password strategy to the original strategy (MySQL8.0 to change its default strategy will cause the password to be unable to match)
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
privileged: true
restart: always
networks:
- testProject_net
#redis容器 - Redis container
redis:
image: redis:6.2.5
container_name: redis
ports:
- 36379:6379
environment:
# 时区上海 - Time zone Shanghai (Change if needed)
TZ: Asia/Shanghai
volumes:
# 数据文件 - data files
- ./data/redis/data:/data:rw
command: "redis-server --requirepass G62m50oigInC30sf --appendonly yes"
privileged: true
restart: always
networks:
- testProject_net
$ docker-compose -f docker-compose-env.yml up -d
go-zero提供了两个操作数据库的库,分别是sqlc和sqlx。区别是前者带缓存,后者不带缓存。
我们先在(六)Go-Zero实战之docker开发环境部署 中创建的usercent服务进行gozero操作数据库相关内容的学习
#!/usr/bin/env bash
# 使用方法:
# ./genModel.sh lottery lottery
# ./genModel.sh lottery prize
# ./genModel.sh looklook_usercenter user_contact
# 再将./genModel下的文件剪切到对应服务的model目录里面,记得改package
#生成的表名
tables=$2
#表生成的genmodel目录
modeldir=./genModel
# 数据库配置
host=127.0.0.1
port=33069
dbname=$1
username=root
passwd=PXDN93VRKUm8TeE7
template=../../goctl/1.6.1
echo "开始创建库:$dbname 的表:$2"
goctl model mysql datasource -url="${username}:${passwd}@tcp(${host}:${port})/${dbname}" -table="${tables}" -dir="${modeldir}" -cache=true --home="${template}" --style=goZero
package config
import (
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/zrpc"
)
type Config struct {
zrpc.RpcServerConf
CheckinRpcConf zrpc.RpcClientConf
JwtAuth struct {
AccessSecret string
AccessExpire int64
}
DB struct {
DataSource string
}
Cache cache.CacheConf
}
package svc
import (
"github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"testProject/app/usercenter/cmd/rpc/internal/config"
"testProject/app/usercenter/model"
)
type ServiceContext struct {
Config config.Config
UserModel model.UserModel
RedisClient *redis.Redis
}
func NewServiceContext(c config.Config) *ServiceContext {
sqlConn := sqlx.NewMysql(c.DB.DataSource)
return &ServiceContext{
UserModel: model.NewUserModel(sqlConn, c.Cache),
Config: c,
}
}
#jwtAuth
JwtAuth:
AccessSecret: ae0536f9-6450-4606-8e13-5a19ed505da0
AccessExpire: 31536000
UserModel: model.NewUserModel(sqlConn, c.Cache),
我们可以基于官方提供的TransactCtx方法,封装自己的事务处理方法
Trans(ctx context.Context, fn func(ctx context.Context, session sqlx.Session) error) error
func (m *defaultUserModel) Trans(ctx context.Context, fn func(ctx context.Context, session sqlx.Session) error) error {
return m.TransactCtx(ctx, func(ctx context.Context, session sqlx.Session) error {
return fn(ctx, session)
})
}
func Md5ByString(str string) string {
m := md5.New()
_, err := io.WriteString(m, str)
if err != nil {
panic(err)
}
arr := m.Sum(nil)
return fmt.Sprintf("%x", arr)
}
func (l *RegisterLogic) Register(in *pb.RegisterReq) (*pb.RegisterResp, error) {
if err := l.svcCtx.UserModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
user := new(model.User)
if len(in.Password) > 0 {
user.Password = tool.Md5ByString(in.Password)
}
insertResult, err := l.svcCtx.UserModel.Insert(ctx, user)
if err != nil {
return errors.Wrapf(err, "Register db user Insert err:%v,user:%+v", err, user)
}
lastId, err := insertResult.LastInsertId()
if err != nil {
return errors.Wrapf(err, "Register db user insertResult.LastInsertId err:%v,user:%+v", err, user)
}
fmt.Println("lastId:", lastId)
return nil
}); err != nil {
logx.Error("Register:", err)
return nil, err
}
return &usercenter.RegisterResp{}, nil
}
至此,我们已经完成了数据库相关配置,以及通过用户服务和注册接口了解到了常规的增删改查操作。
关于更详细的实现,如果有小伙伴有需求,我们可以单独拿一节课来进行详细的拆分讲解。
本篇文章介绍了Go-Zero中的数据库操作,并提供了常用的命令示例。通过学习和实践,我们可以更加熟练地使用Go-Zero进行高效的数据库操作。在后续的文章中,我们将进一步探索数据库操作的高级用法和技巧,为小伙伴们提供更多的参考。
我的文章都首发在同名公众号:王中阳
需要简历优化或者就业辅导,可以直接加我微信:wangzhongyang1993,备注:sf