GO从入门到进阶教程系列 - 研发高性能ORM框架mysql管理多数据源篇

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介:   ↵       上一篇教程我们了解到了基础的GO语法,今天我们来学习如何使用GO开发一个通用的mysql管理器,下面就直接进入步骤环节,代码需要承接上一篇教程的,如有疑问请查看上一篇教程技术版权归属 广州市金狮网络科技有限公司 (https://kingc.
  

       上一篇教程我们了解到了基础的GO语法,今天我们来学习如何使用GO开发一个通用的mysql管理器,下面就直接进入步骤环节,代码需要承接上一篇教程的,如有疑问请查看上一篇教程

技术版权归属 广州市金狮网络科技有限公司 (https://kingc.cn/) ,如需商用请联系公司

1. 编写一个多数据源实例的管理器对象,以及改造下之前的DBConfig对象

// 连接管理器
type RDBManager struct {
	OpenTx   bool    // 是否开启事务
	DsName string  // 数据源名称
	Db     *sql.DB // 非事务实例
	Tx     *sql.Tx // 事务实例
	Errors []error // 操作过程中记录的错误
}
// 数据库配置
type DBConfig struct {
	DsName   string // 数据源名称
	Host     string // 地址IP
	Port     int    // 数据库端口
	Database string // 数据库名称
	Username string // 账号
	Password string // 密码
}

2. 编写初始化多个数据源配置的方法,并改造下我们之前的NewMysql方法

// 初始化数据库实例
func NewMysql(conf DBConfig) (*sql.DB, error) {
	// 定义占位符字符串,使用配置值替换%s和%d
	link := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", conf.Username, conf.Password, conf.Host, conf.Port, conf.Database)
	// 打开mysql获得实例对象
	db, err := sql.Open("mysql", link)
	// 打开mysql失败,返回nil对象,以及返回err对象
	if err != nil {
		return nil, errors.New("mysql初始化失败: " + err.Error())
	}
	// 打开mysql成功返回db对象,err=nil
	return db, nil
}
var (
	MASTER = "MASTER"	// 默认主数据源
	RDBs   = map[string]*RDBManager{} // 初始化时加载数据源到集合
)

// 初始化多个数据库配置文件
func BuildByConfig(input ...DBConfig) {
	if len(input) == 0 {
		panic("数据源配置不能为空")
	}
	for _, v := range input {
		db, err := NewMysql(v)
		panic(err)
		if len(v.DsName) == 0 {
			v.DsName = MASTER
		}
		rdb := &RDBManager{
			Db:     db,
			DsName: v.DsName,
		}
		RDBs[v.DsName] = rdb
	}
}

3. 编写获取数据源的方法,包含是否开启事务,数据源名称参数

// 获取数据源,并控制是否开启事务
func GetDB(openTx bool, ds ...string) (*RDBManager, error) {
	dsName := MASTER
	if len(ds) > 0 && len(ds[0]) > 0 {
		dsName = ds[0]
	}
	rt := RDBs[dsName]
	rdb := &RDBManager{
		OpenTx: openTx,
		Db:     rt.Db,
		DsName: rt.DsName,
		Errors: []error{},
	}
	// 如设置事务,则初始化事务实例
	if rdb.OpenTx {
		tx, err := rdb.Db.Begin()
		if err != nil {
			return nil, errors.New("开启事务失败:" + err.Error())
		}
		rdb.Tx = tx
	}
	return rdb, nil
}

4. 编写释放数据库资源,并提交事务的方法

// 释放资源并提交事务
func (self *RDBManager) Close() {
	if self.OpenTx { // 开启事务操作逻辑
		if len(self.Errors) > 0 { // 如产生异常则回滚事务
			self.Tx.Rollback()
		} else {
			self.Tx.Commit() // 如无异常则提交事务
		}
	}
}


5. 使用获取的数据源进行保存数据操作,我们改造下之前的CRUD方法

// 通过管理器开启事务保存数据
func (self *RDBManager) CRUD1() error {
	// 编写需要执行的sql
	createSql := "insert test_user(username, password, age, sex) values(?,?,?,?)"
	// 预编译sql,事务模式
	stmt, err := self.Tx.Prepare(createSql)
	if err != nil {
		return errors.New("预编译失败: " + err.Error())
	}
	// 提交编译sql对应参数
	ret, err := stmt.Exec("zhangsan", "123456", 18, 1)
	if err != nil {
		return errors.New("提交数据失败: " + err.Error())
	}
	// 保存成功后获取自增ID
	fmt.Println(ret.LastInsertId())
	return nil
}

6. 编写单元测试用例

// 单元测试
func TestCRUD1(t *testing.T) {
	// 数据源配置
	conf := DBConfig{
		DsName:   "test",
		Host:     "127.0.0.1",
		Port:     3306,
		Database: "test",
		Username: "root",
		Password: "123456",
	}
	// 初始化数据源
	BuildByConfig(conf)
	// 获取test数据源
	rdb, err := GetDB(true, "test")
	if err != nil {
		panic(err)
	}
	// 释放资源
	defer rdb.Close()
	// 执行保存数据方法
	if err := rdb.CRUD1(); err != nil {
		panic(err)
	}
}

上面我们已经明白了自定义数据源管理器如何实现,通过示例演示操作,下一篇文章我会讲解如何封装对象转sql入库,敬请期待!

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
开发框架 Go 计算机视觉
纯Go语言开发人脸检测、瞳孔/眼睛定位与面部特征检测插件-助力GoFly快速开发框架
开发纯go插件的原因是因为目前 Go 生态系统中几乎所有现有的人脸检测解决方案都是纯粹绑定到一些 C/C++ 库,如 OpenCV 或 dlib,但通过 cgo 调用 C 程序会引入巨大的延迟,并在性能方面产生显著的权衡。此外,在许多情况下,在各种平台上安装 OpenCV 是很麻烦的。使用纯Go开发的插件不仅在开发时方便,在项目部署和项目维护也能省很多时间精力。
|
3月前
|
Go API 数据库
Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
本文介绍了 Go 语言中常用的 ORM 框架,如 GORM、XORM 和 BeeORM,分析了它们的特点、优势及不足,并从功能特性、性能表现、易用性和社区活跃度等方面进行了比较,旨在帮助开发者根据项目需求选择合适的 ORM 框架。
200 4
|
3月前
|
中间件 Go API
Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架
本文概述了Go语言中几种流行的Web框架,如Beego、Gin和Echo,分析了它们的特点、性能及适用场景,并讨论了如何根据项目需求、性能要求、团队经验和社区支持等因素选择最合适的框架。
203 1
|
5月前
|
JSON Go API
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例
使用Go语言和Gin框架构建RESTful API:GET与POST请求示例
|
6月前
|
Cloud Native JavaScript API
一文读懂云原生 go-zero 微服务框架
一文读懂云原生 go-zero 微服务框架
|
5月前
|
消息中间件 NoSQL Go
PHP转Go系列 | ThinkPHP与Gin框架之Redis延时消息队列技术实践
【9月更文挑战第7天】在从 PHP 的 ThinkPHP 框架迁移到 Go 的 Gin 框架时,涉及 Redis 延时消息队列的技术实践主要包括:理解延时消息队列概念,其能在特定时间处理消息,适用于定时任务等场景;在 ThinkPHP 中使用 Redis 实现延时队列;在 Gin 中结合 Go 的 Redis 客户端库实现类似功能;Go 具有更高性能和简洁性,适合处理大量消息。迁移过程中需考虑业务需求及系统稳定性。
|
6月前
|
Go API 数据库
[go 面试] 分布式事务框架选择与实践
[go 面试] 分布式事务框架选择与实践
|
6月前
|
SQL JavaScript Go
Go Web 服务框架实现详解
Go Web 服务框架实现详解
|
6月前
|
存储 Prometheus 中间件
2020最佳人气项目之Go Web框架
2020最佳人气项目之Go Web框架
|
6月前
|
缓存 监控 中间件
构建高效的Go语言Web服务器:基于Fiber框架的性能优化实践
在追求极致性能的Web开发领域,Go语言(Golang)凭借其高效的并发处理能力、垃圾回收机制及简洁的语法赢得了广泛的青睐。本文不同于传统的性能优化教程,将深入剖析如何在Go语言环境下,利用Fiber这一高性能Web框架,通过精细化配置、并发策略调整及代码层面的微优化,构建出既快速又稳定的Web服务器。通过实际案例与性能测试数据对比,揭示一系列非直觉但极为有效的优化技巧,助力开发者在快节奏的互联网环境中抢占先机。