在go语言中实现使用异步方式读取MySQL数据流程步骤及代码示例
Go  /  管理员 发布于 1年前   379
在Go语言开发中如果出现在数据量很多的情况,我们可以使用异步方式读取MySQL数据库查询数据。
下面来看看如何实现异步读取MySQL数据库查询数据的?
实现异步读取MySQL数据库查询数据函数实现
示例代码:
func getTest(guid, start, end, table string, db *database.GormMysqlDB, model interface{}) ([]LogResp, error) {
// 检查 model 的实际类型
var esct ExtensionServiceClick
var esit ExtensionServiceImpress
//类型断言
switch v := model.(type) {
case ExtensionServiceClick:
esct = v
case ExtensionServiceImpress:
esit = v
default:
return nil, fmt.Errorf("未知的结构体类型")
}
// 继续处理其他逻辑
var totalRecords int64
err := db.ReadTrackingDB.Table(table).Model(&esct).Count(&totalRecords).Error
if err != nil {
return nil, err
}
fmt.Println("读取总数完成:", table, ": ", totalRecords, esit)
// 定义每个 Goroutine 处理的记录范围
recordPerPage := 1000
numWorkers := 5
pageSize := 0
if totalRecords < 5000 {
pageSize = 1
} else {
pageSize = int(totalRecords) / recordPerPage / numWorkers
}
// 使用 WaitGroup 等待所有 Goroutine 完成
var wg sync.WaitGroup
wg.Add(numWorkers)
// 使用 Channel 传递记录给主 Goroutine
recordCh := make(chan interface{})
// 启动多个 Goroutine 并发读取表数据
for i := 0; i < numWorkers; i++ {
go func(offset int) {
defer wg.Done()
var records []LogInfo
// 执行查询语句,读取数据
err := db.ReadTrackingDB.Table(table).Model(&LogInfo{}).Where("create_time >= ? and create_time <= ?", start, end).Offset(offset * pageSize * recordPerPage).Limit(pageSize * recordPerPage).Find(&records).Error
if err != nil {
fmt.Println("查询数据失败:", err)
return
}
for _, record := range records {
recordCh <- record
}
}(i)
}
logRsp := make([]LogResp, 0)
// 启动一个 Goroutine 用于接收并处理数据
go func() {
for record := range recordCh {
// 处理记录
log := LogResp{
Time: timeToStr(record.CreateTime),
Table: table,
Detail: record.Extra,
}
logRsp = append(logRsp, log)
fmt.Println("log:", log, "record:", record)
}
}()
// 等待所有 Goroutine 完成
wg.Wait()
close(recordCh)
fmt.Println("logRsp:", logRsp)
return nil, nil
}
这段代码是一个函数getTest,其目的是从数据库中读取数据并进行处理。
函数接受一些参数,包括 guid、start、end、table、db 和 model,返回一个 []LogResp 类型的切片和一个错误。
代码的主要逻辑如下:
1.首先,通过类型断言将 model 转换为具体的结构体类型 ExtensionServiceClick 或 ExtensionServiceImpress。
如果 model 不是这两种类型之一,则返回一个错误。
然后,使用给定的数据库连接 db 执行查询语句来获取总记录数,并将结果存储在 totalRecords 变量中。
接下来,根据总记录数计算每个 Goroutine 处理的记录范围。
在这里,每个 Goroutine 处理的记录数量由 recordPerPage、numWorkers 和 pageSize 决定。
2.使用 sync.WaitGroup 和 chan 实现并发读取表数据。
首先,创建一个等待组 wg,并使用 wg.Add(numWorkers) 将等待组的计数器设置为 numWorkers。
然后,创建一个 recordCh 通道用于传递记录给主 Goroutine。
3.启动多个 Goroutine 并发读取表数据。
每个 Goroutine 执行查询语句,读取数据,并将每条记录发送到 recordCh 通道中。
4.启动一个 Goroutine 用于接收并处理数据。
该 Goroutine 循环从 recordCh 通道中接收记录,并将其处理后存储在 logRsp 切片中。
5.最后,使用 wg.Wait() 等待所有 Goroutine 完成,并关闭 recordCh 通道。
函数返回 logRsp 切片和一个 nil 错误。
总结
这段代码通过并发读取数据库中的数据,将处理后的结果存储在 logRsp 切片中,并返回给调用方。
使用 sync.WaitGroup 和 chan 可以实现并发的数据处理和同步。
123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..路人 在
php中使用hyperf框架调用讯飞星火大模型实现国内版chatgpt功能示例中评论 教程很详细,如果加个前端chatgpt对话页面就完美了..Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号