Go语言之GORM框架(二) ——GORM的单表操作

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
日志服务 SLS,月写入数据量 50GB 1个月
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: Go语言之GORM框架(二) ——GORM的单表操作

前言

在上一篇文章中,我们对Gorm进行了介绍,而在这一篇文章中我们主要介绍GORM的单表查询与Hook函数,在进行今天的内容之前我们先事先说明一下,下面我们对单表进行操作的表结构如下:

type Student struct {
  ID   uint   `gorm:"size:3"`
  Name string `gorm:"size:8"`
  Age  int    `gorm:"size:3"`
  Sex  string `gorm:"size:3"`
  Email *string `gorm:"size:32"`
}

好了,话不多说,开始我们今天的内容

表的初始化

首先我们确定一下我们已经将要演示的数据库内相关内容清空掉了,然后我们就可以开始连接数据库并创建students表了:

package main
import (
  "fmt"
  "gorm.io/driver/mysql"
  "gorm.io/gorm"
)
type Student struct {
  ID    uint    `gorm:"size:3"`
  Name  string  `gorm:"size:8"`
  Age   int     `gorm:"size:3"`
  Sex   string  `gorm:"size:3"`
  Email *string `gorm:"size:32"`
}
var myDB *gorm.DB
func init() {
  user := "root"
  password := "aaaa"
  dbname := "gorm"
  ip := "127.0.0.1"
  port := "3306"
  dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", user, password, ip, port, dbname)
  db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
  if err != nil {
    fmt.Println("数据库连接失败,err:", err)
    return
  }
  fmt.Println("数据库连接成功")
  myDB = db
}
func main() {
  err := myDB.AutoMigrate(&Student{})
  if err != nil {
    fmt.Println("students表创建失败,err:", err)
    return
  }
  fmt.Println("students表创建成功")
}

单表操作

创建并插入数据

插入单条数据

func SingleInsert(student Student) {
  res := myDB.Create(&student)
  if res.Error != nil {
    fmt.Println("插入数据失败,err:", res.Error)
    return
  }
  fmt.Println("插入数据成功")
}
func main() {
  err := myDB.AutoMigrate(&Student{})
  if err != nil {
    fmt.Println("students表创建失败,err:", err)
    return
  }
  fmt.Println("students表创建成功")
  email := "fengxu@163.com"
  student := Student{
    Name:  "fengxu",
    Age:   18,
    Sex:   "男",
    Email: &email,
  }
  SingleInsert(student)
}

运行成功,查找数据库:

这样我们就成功将一条记录插入数据库了

批量插入数据

func Insert(StudentList []Student) {
  var StudentList []Student
  for i := 0; i < 10; i++ {
    email := fmt.Sprintf("No.%d@163.com", i)
    student := Student{
      Name:  fmt.Sprintf("No.%d", i),
      Age:   18 + i,
      Sex:   "男",
      Email: &email,
    }
    StudentList = append(StudentList, student)
  }
  res := myDB.Create(&StudentList)
  if res.Error != nil {
    fmt.Println("插入数据失败,err:", res.Error)
    return
  }
  fmt.Println("插入数据成功")
}

这显示我们成功向students表中批量插入数据。

插入数据的细节

  • 这里的email我为了表示它可以为空,将它的类型设置成了指针,所以我们在传值的时候也要传指针
  • 我们在使用Create函数时,传递的是指针,而不是具体值
  • 由于我们传入到Create函数的是student的指针,所以student在此之后就会出现该记录的其他消息了,比如下面这样:
func SingleInsert(student Student) {
  //插入单条数据
  email := "fengxu@163.com"
  student := Student{
    Name:  "luoyu",
    Age:   18,
    Sex:   "男",
    Email: &email,
  }
  SingleInsert(student)
  res := myDB.Create(&student)
  if res.Error != nil {
    fmt.Println("插入数据失败,err:", res.Error)
    return
  }
  fmt.Println("插入数据成功")
  fmt.Println(student)
}

打印的结果为:

{13 luoyu 18 男 0xc0001e0830}

单表插入的完整代码:

package main
import (
  "fmt"
  "gorm.io/driver/mysql"
  "gorm.io/gorm"
)
type Student struct {
  ID    uint    `gorm:"size:3"`
  Name  string  `gorm:"size:8"`
  Age   int     `gorm:"size:3"`
  Sex   string  `gorm:"size:3"`
  Email *string `gorm:"size:32"`
}
var myDB *gorm.DB
func init() {
  user := "root"
  password := "ba161754"
  dbname := "gorm"
  ip := "127.0.0.1"
  port := "3306"
  dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", user, password, ip, port, dbname)
  db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
  if err != nil {
    fmt.Println("数据库连接失败,err:", err)
    return
  }
  fmt.Println("数据库连接成功")
  myDB = db
}
func SingleInsert(student Student) {
  res := myDB.Create(&student)
  if res.Error != nil {
    fmt.Println("插入数据失败,err:", res.Error)
    return
  }
  fmt.Println("插入数据成功")
  fmt.Println(student)
}
func Insert(StudentList []Student) {
  res := myDB.Create(&StudentList)
  if res.Error != nil {
    fmt.Println("插入数据失败,err:", res.Error)
    return
  }
  fmt.Println("插入数据成功")
}
func main() {
  err := myDB.AutoMigrate(&Student{})
  if err != nil {
    fmt.Println("students表创建失败,err:", err)
    return
  }
  fmt.Println("students表创建成功")
  //插入单条数据
  email := "fengxu@163.com"
  student := Student{
    Name:  "luoyu",
    Age:   18,
    Sex:   "男",
    Email: &email,
  }
  SingleInsert(student)
  //批量插入数据
  var StudentList []Student
  for i := 0; i < 10; i++ {
    email := fmt.Sprintf("No.%d@163.com", i)
    student := Student{
      Name:  fmt.Sprintf("No.%d", i),
      Age:   18 + i,
      Sex:   "男",
      Email: &email,
    }
    StudentList = append(StudentList, student)
  }
  Insert(StudentList)
}

单表查询

前言

在讲解单表查询之前,我们先来看一个很简单的单表查询代码

package main
import (
  "fmt"
  "gorm.io/driver/mysql"
  "gorm.io/gorm"
  "gorm.io/gorm/logger"
  "log"
  "os"
  "time"
)
type Student struct {
  ID    uint    `gorm:"size:3"`
  Name  string  `gorm:"size:8"`
  Age   int     `gorm:"size:3"`
  Sex   string  `gorm:"size:3"`
  Email *string `gorm:"size:32"`
}
var myDB *gorm.DB
var mysqllogger logger.Interface
func init() {
  user := "root"
  password := "ba161754"
  dbname := "gorm"
  ip := "127.0.0.1"
  port := "3306"
  dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", user, password, ip, port, dbname)
  db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
  if err != nil {
    fmt.Println("数据库连接失败,err:", err)
    return
  }
  fmt.Println("数据库连接成功")
  myDB = db
}
func initLogger() {
  var mysqlLogger logger.Interface
  mysqlLogger = logger.Default.LogMode(logger.Info) //设置日志打印级别
  mysqlLogger = logger.New(
    log.New(os.Stdout, "\r\n", log.LstdFlags), // (日志输出的目标,前缀和日志包含的内容)
    logger.Config{
      SlowThreshold:             time.Second, // 慢 SQL 阈值
      LogLevel:                  logger.Info, // 日志级别
      IgnoreRecordNotFoundError: true,        // 忽略ErrRecordNotFound(记录未找到)错误
      Colorful:                  true,        // 使用彩色打印
    },
  )
  myDB.Logger = mysqlLogger
}
func main() {
  var student Student
  initLogger()
  myDB.Session(&gorm.Session{
    Logger: mysqllogger,
  })
  myDB.Take(&student) //默认查找第一条数据
  fmt.Println(student)
  student = Student{}
  myDB.First(&student) //查找第一条数据
  fmt.Println(student)
  student = Student{}
  myDB.Last(&student) //查找最后一条数据
  fmt.Println(student)
}

输出结果为:

这里我在打印出查询结果的同时也打印出了它们原生的sql语句,我们可以看到相对于原生sql语句,GORM的语句相对比较简单。

当然和我们平时利用各种各样的筛选条件来进行查询,我们在GORM也可以利用各种各样的条件来完成查询,,最后我们介绍一下下面我们可能会使用的函数:

  • Take:用于从数据库中检索符合条件的第一条记录,并将其填充到指定的结构体中。如果没有指定特定的条件,它会默认返回第一条记录。
  • Find:用于从数据库中检索符合条件的所有记录,并将它们填充到指定的结构体切片中。你可以使用Where函数来添加条件限制,以便只检索满足特定条件的记录。

单条记录查询

  • 根据主键查询
myDB.Take(&student, 1)
  fmt.Println(student)
  myDB.Take(&student, "1")
  fmt.Println(student)

注意:这里指定主键时可以是数字也可以是字符串

  • 根据其他条件来查询
myDB.Take(&student, "name = ?", "fengxu")
  fmt.Println(student)

这里我们用?来作为占位符,这样可以有效的防止sql注入

  • 根据struct来查询
myDB.Where(&Student{Name: "fengxu"}).Find(&student)
  fmt.Println(student)
  student = Student{}
  • 获取查询结果
var studentList []Student
    err := myDB.Find(&studentList).Error
  switch {
  case errors.Is(err, gorm.ErrRecordNotFound):
    fmt.Println("没有找到数据")
  default:
    fmt.Println("sql语句出现问题")
  }
  count := myDB.Find(&studentList).RowsAffected  //获取查询结果条数
  fmt.Println(count)
}

完整代码:

func SingleSerach() {
  var student Student
  var studentList []Student
  //根据主键查询
  myDB.Take(&student, 1)
  fmt.Println(student)
  student = Student{}
  myDB.Take(&student, "3")
  fmt.Println(student)
  student = Student{}
  //根据字段查询
  myDB.Take(&student, "name = ?", "fengxu")
  fmt.Println(student)
  student = Student{}
  //根据struct来查询
  //student.ID = 4
  myDB.Where(&Student{Name: "fengxu"}).Find(&student)
  fmt.Println(student)
  student = Student{}
  err := myDB.Find(&studentList).Error
  switch {
  case errors.Is(err, gorm.ErrRecordNotFound):
    fmt.Println("没有找到数据")
  default:
    fmt.Println("sql语句出现问题")
  }
  count := myDB.Find(&studentList).RowsAffected
  fmt.Println(count)
}

多条记录查询

  • 简单示例:
func MultipleSearch() {
  var studentList []Student
  myDB.Find(&studentList)
  for _, v := range studentList {
    fmt.Println(v)
  }
  //上面我们打印的email是地址,我们需要对它进行序列化
  for _, v := range studentList {
    data, _ := json.Marshal(v)
    fmt.Println(string(data))
  }
}
  • 按照主键来查询
studentList1 := []Student{}
  myDB.Find(&studentList1, 1, 2, 3, 4, 5, 6)
  for _, v := range studentList1 {
    data, _ := json.Marshal(v)
    fmt.Println(string(data))
  }
  studentList2 := []Student{}
  myDB.Find(&studentList2, []int{1, 2, 3, 4, 5, 6})
  for _, v := range studentList2 {
    data, _ := json.Marshal(v)
    fmt.Println(string(data))
  }

注意:这里其实用不用前片都可以,但是测试结果是切片速度明显较快,建议使用切片

  • 按照其他条件来查询
//根据字段查询
  studentList := []Student{}
  myDB.Where("name in ?", []string{"fengxu", "luoyu"}).Find(&studentList)
  for _, v := range studentList {
    data, _ := json.Marshal(v)
    fmt.Println(string(data))
  }

全部代码:

func MultipleSearch() {
  var studentList []Student
  myDB.Find(&studentList)
  for _, v := range studentList {
    fmt.Println(v)
  }
  //按主键查询
  studentList1 := []Student{}
  myDB.Find(&studentList1, 1, 2, 3, 4, 5, 6)
  for _, v := range studentList1 {
    data, _ := json.Marshal(v)
    fmt.Println(string(data))
  }
  
  studentList2 := []Student{}
  myDB.Find(&studentList2, []int{1, 2, 3, 4, 5, 6})
  for _, v := range studentList2 {
    data, _ := json.Marshal(v)
    fmt.Println(string(data))
  }
  //根据字段查询
  studentList = []Student{}
  myDB.Where("name in ?", []string{"fengxu", "luoyu"}).Find(&studentList)
  for _, v := range studentList {
    data, _ := json.Marshal(v)
    fmt.Println(string(data))
  }
}

单表数据的更新

示例:

func Update() {
  var student Student
  myDB.Take(&student, 1)
  student.Name = "三玖"
  student.Sex = "女"
  myDB.Save(&student)
  fmt.Println(student)
}

注意:

  • Save会保留所有的字段,哪怕我们将字段的值设为0
  • Save函数其实是一个组合操作,如果当前不存在该字段,则是执行Create否则执行Update
  • 不要将 SaveModel一同使用, 这是 未定义的行为

单列更新

  • 更新单列指定字段
//更新指定字段
  student = Student{}
  myDB.Take(&student)
  student.Age = 19
  myDB.Select("age").Save(&student)
  fmt.Println(student)
  • 批量更新
//同时更新单个指定字段
  studentList := []Student{}
  myDB.Where("name like ?", "No.%").Find(&studentList).Update("age", 19)
  for _, v := range studentList {
    fmt.Println(v.Name, v.Age)
  }
  
  //同时更新多个指定字段
  Email := "sanjiu@163.com"
  new_student := Student{
    Age:   20,
    Sex:   "女",
    Email: &Email,
  }
  myDB.Model(&student).Where("name=?", "三玖").Updates(new_student)  //方法一:struct
  
  myDB.Model(&student).Where("name=?", "三玖").Updates(map[string]interface{}{
    "age":   20,
    "sex":   "女",
    "email": "sanjiu@163.com",
  })//  方法二:map

注意:Updates函数在struct方法更新字段时会自动忽略零值,如果想避免建议使用map或使用Select函数说明一下要更新的字段,示例如下:

DB.Model(&Student{}).Where("age = ?", 21).Select("gender", "email").Updates(Student{
  Email:  &email,
  Gender: false,
})

单表删除

func Delete() {
  var student Student
  var studentlist []Student
  myDB.Take(&student, 1)
  myDB.Delete(&student) //单行删除
  myDB.Take(&studentlist, []int{1, 2, 3})
  myDB.Delete(&studentlist) //批量删除
}

代码汇总

以上有关单表操作的全部代码:

package main
import (
  "encoding/json"
  "errors"
  "fmt"
  "gorm.io/driver/mysql"
  "gorm.io/gorm"
  "gorm.io/gorm/logger"
  "log"
  "os"
  "time"
)
type Student struct {
  ID    uint    `gorm:"size:3"`
  Name  string  `gorm:"size:8"`
  Age   int     `gorm:"size:3"`
  Sex   string  `gorm:"size:3"`
  Email *string `gorm:"size:32"`
}
var myDB *gorm.DB
var mysqllogger logger.Interface
func init() {
  user := "root"
  password := "nicai"
  dbname := "gorm"
  ip := "127.0.0.1"
  port := "3306"
  dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", user, password, ip, port, dbname)
  db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
  if err != nil {
    fmt.Println("数据库连接失败,err:", err)
    return
  }
  fmt.Println("数据库连接成功")
  myDB = db
}
func initLogger() {
  var mysqlLogger logger.Interface
  mysqlLogger = logger.Default.LogMode(logger.Info) //设置日志打印级别
  mysqlLogger = logger.New(
    log.New(os.Stdout, "\r\n", log.LstdFlags), // (日志输出的目标,前缀和日志包含的内容)
    logger.Config{
      SlowThreshold:             time.Second, // 慢 SQL 阈值
      LogLevel:                  logger.Info, // 日志级别
      IgnoreRecordNotFoundError: true,        // 忽略ErrRecordNotFound(记录未找到)错误
      Colorful:                  true,        // 使用彩色打印
    },
  )
  myDB.Logger = mysqlLogger
}
func SingleSerach() {
  var student Student
  var studentList []Student
  //根据主键查询
  myDB.Take(&student, 1)
  fmt.Println(student)
  student = Student{}
  myDB.Take(&student, "3")
  fmt.Println(student)
  student = Student{}
  //根据字段查询
  myDB.Take(&student, "name = ?", "fengxu")
  fmt.Println(student)
  student = Student{}
  //根据struct来查询
  //student.ID = 4
  myDB.Where(&Student{Name: "fengxu"}).Find(&student)
  fmt.Println(student)
  student = Student{}
  err := myDB.Find(&studentList).Error
  switch {
  case errors.Is(err, gorm.ErrRecordNotFound):
    fmt.Println("没有找到数据")
  default:
    fmt.Println("sql语句出现问题")
  }
  count := myDB.Find(&studentList).RowsAffected
  fmt.Println(count)
}
func MultipleSearch() {
  var studentList []Student
  myDB.Find(&studentList)
  for _, v := range studentList {
    fmt.Println(v)
  }
  //按主键查询
  studentList1 := []Student{}
  myDB.Find(&studentList1, 1, 2, 3, 4, 5, 6)
  for _, v := range studentList1 {
    data, _ := json.Marshal(v)
    fmt.Println(string(data))
  }
  studentList2 := []Student{}
  myDB.Find(&studentList2, []int{1, 2, 3, 4, 5, 6})
  for _, v := range studentList2 {
    data, _ := json.Marshal(v)
    fmt.Println(string(data))
  }
  //根据字段查询
  studentList = []Student{}
  myDB.Where("name in ?", []string{"fengxu", "luoyu"}).Find(&studentList)
  for _, v := range studentList {
    data, _ := json.Marshal(v)
    fmt.Println(string(data))
  }
}
func Update() {
  //update操作示例
  var student Student
  myDB.Take(&student, 1)
  student.Name = "三玖"
  student.Sex = "女"
  myDB.Save(&student)
  fmt.Println(student)
  //更新指定字段
  student = Student{}
  myDB.Take(&student)
  student.Age = 19
  myDB.Select("age").Save(&student)
  fmt.Println(student)
  //同时更新多列的指定字段
  studentList := []Student{}
  myDB.Where("name like ?", "No.%").Find(&studentList).Update("age", 19)
  for _, v := range studentList {
    fmt.Println(v.Name, v.Age)
  }
  //同时更新多列
  Email := "sanjiu@163.com"
  new_student := Student{
    Age:   20,
    Sex:   "女",
    Email: &Email,
  }
  myDB.Model(&student).Where("name=?", "三玖").Updates(new_student) //方法一:struct
  myDB.Model(&student).Where("name=?", "三玖").Updates(map[string]interface{}{
    "age":   20,
    "sex":   "女",
    "email": "sanjiu@163.com",
  }) //  方法二:map
}
func Delete() {
  var student Student
  var studentlist []Student
  myDB.Take(&student, 1)
  myDB.Delete(&student) //单行删除
  myDB.Take(&studentlist, []int{1, 2, 3})
  myDB.Delete(&studentlist) //批量删除
}
func main() {
  //var student Student
  initLogger()
  myDB.Session(&gorm.Session{
    Logger: mysqllogger,
  })
  //myDB.Take(&student) //默认查找第一条数据
  //fmt.Println(student)
  //student = Student{}
  //
  //myDB.First(&student) //查找第一条数据
  //fmt.Println(student)
  //student = Student{}
  //
  //myDB.Last(&student) //查找最后一条数据
  //fmt.Println(student)
  Delete()
}

结语

上面仅仅是我基于Gorm框架学习的一些笔记,详细可以参考:

GORM官方文档

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
1月前
|
数据采集 Go API
Go语言实战案例:多协程并发下载网页内容
本文是《Go语言100个实战案例 · 网络与并发篇》第6篇,讲解如何使用 Goroutine 和 Channel 实现多协程并发抓取网页内容,提升网络请求效率。通过实战掌握高并发编程技巧,构建爬虫、内容聚合器等工具,涵盖 WaitGroup、超时控制、错误处理等核心知识点。
|
1月前
|
数据采集 JSON Go
Go语言实战案例:实现HTTP客户端请求并解析响应
本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。
|
2月前
|
JSON 前端开发 Go
Go语言实战:创建一个简单的 HTTP 服务器
本篇是《Go语言101实战》系列之一,讲解如何使用Go构建基础HTTP服务器。涵盖Go语言并发优势、HTTP服务搭建、路由处理、日志记录及测试方法,助你掌握高性能Web服务开发核心技能。
|
2月前
|
Go
如何在Go语言的HTTP请求中设置使用代理服务器
当使用特定的代理时,在某些情况下可能需要认证信息,认证信息可以在代理URL中提供,格式通常是:
205 0
|
3月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:路由、中间件、参数校验
Gin框架以其极简风格、强大路由管理、灵活中间件机制及参数绑定校验系统著称。本文详解其核心功能:1) 路由管理,支持分组与路径参数;2) 中间件机制,实现全局与局部控制;3) 参数绑定,涵盖多种来源;4) 结构体绑定与字段校验,确保数据合法性;5) 自定义校验器扩展功能;6) 统一错误处理提升用户体验。Gin以清晰模块化、流程可控及自动化校验等优势,成为开发者的优选工具。
|
3月前
|
JSON 编解码 API
Go语言网络编程:使用 net/http 构建 RESTful API
本章介绍如何使用 Go 语言的 `net/http` 标准库构建 RESTful API。内容涵盖 RESTful API 的基本概念及规范,包括 GET、POST、PUT 和 DELETE 方法的实现。通过定义用户数据结构和模拟数据库,逐步实现获取用户列表、创建用户、更新用户、删除用户的 HTTP 路由处理函数。同时提供辅助函数用于路径参数解析,并展示如何设置路由器启动服务。最后通过 curl 或 Postman 测试接口功能。章节总结了路由分发、JSON 编解码、方法区分、并发安全管理和路径参数解析等关键点,为更复杂需求推荐第三方框架如 Gin、Echo 和 Chi。
|
3月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:使用 Gin 快速构建 Web 服务
Gin 是一个高效、轻量级的 Go 语言 Web 框架,支持中间件机制,非常适合开发 RESTful API。本文从安装到进阶技巧全面解析 Gin 的使用:快速入门示例(Hello Gin)、定义 RESTful 用户服务(增删改查接口实现),以及推荐实践如参数校验、中间件和路由分组等。通过对比标准库 `net/http`,Gin 提供更简洁灵活的开发体验。此外,还推荐了 GORM、Viper、Zap 等配合使用的工具库,助力高效开发。
|
4月前
|
分布式计算 Go C++
初探Go语言RPC编程手法
总的来说,Go语言的RPC编程是一种强大的工具,让分布式计算变得简单如同本地计算。如果你还没有试过,不妨挑战一下这个新的编程领域,你可能会发现新的世界。
105 10
|
7月前
|
存储 缓存 安全
Go 语言中的 Sync.Map 详解:并发安全的 Map 实现
`sync.Map` 是 Go 语言中用于并发安全操作的 Map 实现,适用于读多写少的场景。它通过两个底层 Map(`read` 和 `dirty`)实现读写分离,提供高效的读性能。主要方法包括 `Store`、`Load`、`Delete` 等。在大量写入时性能可能下降,需谨慎选择使用场景。
|
10月前
|
存储 负载均衡 监控
如何利用Go语言的高效性、并发支持、简洁性和跨平台性等优势,通过合理设计架构、实现负载均衡、构建容错机制、建立监控体系、优化数据存储及实施服务治理等步骤,打造稳定可靠的服务架构。
在数字化时代,构建高可靠性服务架构至关重要。本文探讨了如何利用Go语言的高效性、并发支持、简洁性和跨平台性等优势,通过合理设计架构、实现负载均衡、构建容错机制、建立监控体系、优化数据存储及实施服务治理等步骤,打造稳定可靠的服务架构。
211 1