百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

go-zero 微服务框架集成 gorm 实操

ccwgpt 2025-08-03 04:16 3 浏览 0 评论

作为服务,肯定要和数据库交互的,所以在 go-zero 框架里集成 数据库 的操作是必不可少的,今天看看 go-zero 的 rpc 应用如何集成 gorm 框架。

总体的思路分这几步:

  • 定义你的配置项结构体
  • 定义你的配置
  • 添加到 svcContext
  • 实现你的模型
  • 具体业务逻辑的应用

1.config 的结构体

package config

import (
	"github.com/zeromicro/go-zero/zrpc"
)

type Config struct {
	zrpc.RpcServerConf
	MySQLConf MySQLConf
}

// Mysql config
type MySQLConf struct {
	Host 					  string 		`json:"" yaml:"Host"`
	Port 					  int64 		`json:"" yaml:"Port"`
	User 					  string 		`json:"" yaml:"User"`
	Password				  string 		`json:"" yaml:"Password"`
	Database 				  string 		`json:"" yaml:"Database"`
	CharSet 			 	  string 		`json:"" yaml:"CharSet"`
	TimeZone 				  string 		`json:"" yaml:"TimeZone"`
	ParseTime 				  bool 			`json:"" yaml:"ParseTime"`
	Enable                    bool          `json:"" yaml:"Enable"`					   // use mysql or not

	//DefaultStringSize         uint          `json:"" yaml:"DefaultStringSize"`         // string 类型字段的默认长度
	AutoMigrate 			  bool 			`json:"" yaml:"AutoMigrate"`
	//DisableDatetimePrecision  bool          `json:"" yaml:"DisableDatetimePrecision"`  // 禁用 datetime 精度
	//SkipInitializeWithVersion bool          `json:"" yaml:"SkipInitializeWithVersion"` // 根据当前 MySQL 版本自动配置
	//
	//SlowSql                   time.Duration `json:"" yaml:"SlowSql"`                   //慢SQL
	//LogLevel                  string        `json:"" yaml:"LogLevel"`                  // 日志记录级别
	//IgnoreRecordNotFoundError bool          `json:"" yaml:"IgnoreRecordNotFoundError"` // 是否忽略ErrRecordNotFound(未查到记录错误)

	Gorm                      GormConf          `json:"" yaml:"Gorm"`
}

// gorm config
type GormConf struct {
	//SkipDefaultTx   bool   `json:"" yaml:"SkipDefaultTx"`                            //是否跳过默认事务
	//CoverLogger     bool   `json:"" yaml:"CoverLogger"`                              //是否覆盖默认logger
	//PreparedStmt    bool   `json:"" yaml:"PreparedStmt"`                              // 设置SQL缓存
	//CloseForeignKey bool   `json:"" yaml:"CloseForeignKey"` 						// 禁用外键约束
	SingularTable   bool   `json:"" yaml:"SingularTable"`                            //是否使用单数表名(默认复数),启用后,User结构体表将是user
	TablePrefix     string `json:"" yaml:"TablePrefix"`                              // 表前缀
	MaxOpenConns int `json:"" yaml:"MaxOpenConns"`
	MaxIdleConns int `json:"" yaml:"MaxIdleConns"`
	ConnMaxLifetime int `json:"" yaml:"ConnMaxLifetime"`
}

2.配置文件声明

MySQLConf:
  Enable: true
  User: user1
  Password: user1
  Host: x.x.x.x
  Port: 3306
  Database: zero
  CharSet: utf8
  ParseTime: true
  TimeZOne: Local
  AutoMigrate: true
  Gorm:
    TablePrefix: zero_
    SingularTable: true
    MaxOpenConns: 100
    MaxIdleConns: 5
    ConnMaxLifetime: 600

3.添加 svcContext

package svc

import (
	"fmt"
	"time"

	"userrpcv1/internal/config"
	"userrpcv1/internal/models"

	"github.com/zeromicro/go-zero/core/logx"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
)

type ServiceContext struct {
	Config config.Config

	// claim ur redis client in here
	//RedisClient *zeroRds.Redis

	// claim ur mysql here
	DBEngine *gorm.DB
}

func NewServiceContext(c config.Config) *ServiceContext {
	// redis
	//conf := c.Redis
	//redisClient := zeroRds.MustNewRedis(conf.RedisConf)

	// mysql
	mysqlConf := c.MySQLConf
	var db *gorm.DB
	var err error
	if mysqlConf.Enable {
		db, err = creteDbClient(mysqlConf)
		if err != nil {
			db = nil
		}
	}

	return &ServiceContext{
		Config: c,

		//RedisClient: redisClient,

		DBEngine: db,
	}
}

func creteDbClient(mysqlConf config.MySQLConf) (*gorm.DB, error) {
	datasource := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=%t&loc=%s",
		mysqlConf.User,
		mysqlConf.Password,
		mysqlConf.Host,
		mysqlConf.Port,
		mysqlConf.Database,
		mysqlConf.CharSet,
		mysqlConf.ParseTime,
		mysqlConf.TimeZone)
	db, err := gorm.Open(mysql.Open(datasource), &gorm.Config{
		NamingStrategy: schema.NamingStrategy{
			TablePrefix: mysqlConf.Gorm.TablePrefix, // such as: prefix_tableName
			SingularTable: mysqlConf.Gorm.SingularTable, // such as zero_user, not zero_users
		},
	})
	if err != nil {
		logx.Errorf("create mysql db failed, err: %v", err)
		return nil, err
	}

	// auto sync table structure, no need to create table
	err = db.AutoMigrate(&models.User{})
	if err != nil {
		logx.Errorf("automigrate table failed, err: %v", err)
	}

	logx.Info("init mysql client instance success.")

	sqlDB, err := db.DB()
	if err != nil {
		logx.Errorf("mysql set connection pool failed, err: %v.", err)
		return nil, err
	}
	sqlDB.SetMaxOpenConns(mysqlConf.Gorm.MaxOpenConns)
	sqlDB.SetMaxIdleConns(mysqlConf.Gorm.MaxIdleConns)
	sqlDB.SetConnMaxLifetime(time.Duration(mysqlConf.Gorm.ConnMaxLifetime) * time.Second)

	return db, nil
}

4.定义你的相关表或者模型

models/user.go

package models

import "time"

// base model
type BaseModel struct {
	ID        int64     `json:"id" gorm:"column:id;autoIncrement;primaryKey"`
	CreatedAt time.Time `json:"createdAt" gorm:"column:createdAt"`
	UpdatedAt time.Time `json:"updatedAt" gorm:"column:updatedAt"`
	DeletedAt time.Time `json:"-" gorm:"column:deletedAt"`
}

// user table
type User struct {
	BaseModel
	Username string `json:"username" gorm:"column:username;type:varchar(20);unique:un_username;not null;comment:用户名"`
	NickName string `json:"nickName" gorm:"column:nickname;type:varchar(20);not null;default:'-';comment:昵称"`
	Phone    int    `json:"phone" gorm:"column:phone;type:int;unique:un_phone;comment:手机号"`
	Password string `json:"-" gorm:"column:password;type:varchar(40);comment:密码"`
	Status   int8   `json:"status" gorm:"column:status;size:4;default:1;comment:状态 1:正常 2:白名单 3:黑名单"`
	IsAdmin  bool   `json:"is_admin" gorm:"column:is_admin;default:false"`
}

// userProfile table
type UserInfo struct {
	BaseModel
	Address string `json:"address" gorm:"column:address;type:varchar(100)"`
	Uid     uint   `json:"uid" gorm:"column:uid;comment:用户id"`
}

接着你就可以拿到 db 在你的业务逻辑进行操作了。

注意这里需要先创建相关的数据库。

相关推荐

土豪农村建个别墅不新鲜 建个车库都用框架结构?

农村建房子过去都是没车库,也没有那么多豪车,一般直接停在路边或者院子里。现在很多人都会在建房子的时候留一个车库,通过车库可以直接进入客厅,省得雨雪天气折腾。农村土豪都是有钱任性,建房子跟我们普通人不一...

自建框架结构出现裂缝怎么回事?

三层自建房梁底与墙体连接处裂缝是结构问题吗?去前帮我姑画了一份三层自建房的图纸,前天他们全部装修好了。我姑丈突然打电话给我说他发现二层的梁底与墙分离了,有裂缝。也就是图纸中前面8.3米那跨梁与墙体衔接...

钢结构三维图集-框架结构(钢柱对接)

1、实腹式钢柱对接说明1:1.上节钢柱的安装吊点设置在钢柱的上部,利用四个吊点进行吊装;2.吊装前,下节钢柱顶面和本节钢柱底面的渣土和浮锈要清除干净,保证上下节钢柱对接面接触顶紧;3.钢柱吊装到位后...

三层框架结构主体自建房设计案例!布局13*12米占地面积156平米!

绘创意设计乡村好房子设计小编今日头条带来分享一款:三层框架结构主体自建房设计案例!布局13*12米占地面积156平米!本案例设计亮点:这是一款三层新中式框架结构自建房,占地13×12米,户型占地面积...

Casemaker机箱框架结构3D图纸 STEP格式

农村自建房新宠!半框架结构凭啥这么火?内行人揭开3个扎心真相

回老家闲逛,竟发现个有意思的现象:村里盖新房,十家有八家都选了"半框架结构"。隔壁王叔家那栋刚封顶的二层小楼,外墙红砖还露着糙面没勾缝,里头的水泥柱子倒先支棱得笔直,这到底是啥讲究?蹲...

砖混结构与框架结构!究竟有何区别?千万别被坑!

农村自建房选结构,砖混省钱但出事真能保命吗?7月建材价格波动期,多地建房户因安全焦虑陷入选择困境——框架结构虽贵30%,却是地震区保命的关键。框架柱和梁组成的承重体系,受力分散得像一张网。砖混靠墙硬扛...

砖混结构与框架结构,究竟有何区别?千万别被坑!

农村建房选砖混结构还是框架结构?这个问题算是近期留言板里问得最多的问题了。今天咱们说说二者的区别,帮您选个合适的。01成本区别假如盖一栋砖混结构的房子需要30万,那么换成框架结构,一般要多掏30%的费...

6个小众却逆天的App神器,个个都是黑科技的代表

你的手机上有哪些好用的软件?今天我就给大家分享6个小众却逆天的App神器,个个都是黑科技的代表!01*Via浏览器推荐理由:体积极小的浏览器,没有任何广告。使用感受:它的体量真的很小,只有702KB,...

合肥App开发做一个app需要多少钱?制作周期有多久?

在移动互联网时代,开发一款APP已成为企业数字化转型与个人创业的重要途径。然而,APP的开发成本与制作周期受功能复杂度、技术架构、团队类型等多重因素影响,差异极大。好牛软件将从这两个维度展开分析,帮助...

详解应对App臃肿化的五大法则

编者注:本文转自腾讯ISUX。先来看一张图:图上看到,所有平台上用户花费时间都在减少,除了移动端。观察身边也是如此,回家不开电脑的小伙伴越来越多。手机平板加电视,下班场景全搞定。连那些以前电脑苦手的...

实战!如何从零搭建10万级 QPS 大流量、高并发优惠券系统

需求背景春节活动中,多个业务方都有发放优惠券的需求,且对发券的QPS量级有明确的需求。所有的优惠券发放、核销、查询都需要一个新系统来承载。因此,我们需要设计、开发一个能够支持十万级QPS的券系...

8种移动APP导航设计模式大对比

当我们确定了移动APP的设计需求和APP产品设计流程之后,开始着手设计APP界面UI或是APP原型图啦。这个时候我们都要面临的第一个问题就是如何将信息以最优的方式组合起来?也许我们对比和了解了其他一些...

数字资产支付 App 的技术框架

开发一款功能强大、安全可靠的数字资产支付App需要一个整合了区块链技术、后端服务、前端应用以及第三方集成的全栈技术框架。这个框架的核心在于保障数字资产的安全流通,并将其高效地桥接到传统的法币支付场...

从MyBatis到App架构:设计模式全景应用指南

从MyBatis到App架构:设计模式全景应用指南引言在企业级应用和服务端开发领域,MyBatis凭借其灵活、简洁、强大的ORM映射能力被广泛应用。而它之所以能拥有如此优秀的可扩展性和工程可维护性,正...

取消回复欢迎 发表评论: