【MySQL】Go操作MySQL从入门到实战:环境搭建+语法+CRUD全解析
大家好呀~ 今天来跟大家分享「Go 操作 MySQL」的完整实战教程!不管你是刚入门 Go 的新手,还是想拓展后端技能栈的开发者,这篇文章都会从环境搭建到实战代码,一步步带你搞定 Go 与 MySQL 的联动~ 文中关键代码都可直接复制运行,亲测无坑!
一、Go 开发环境准备
1. Windows 安装 Go
- 官方下载地址:https://golang.google.cn/dl/(推荐下载稳定版)
- 避坑提醒:win10 安装时若出现错误代码 2503/2502,可参考这篇解决方案:https://jingyan.baidu.com/article/75ab0bcb9de916d6874db25a.html
- 环境变量配置:安装完成后,右键「此电脑」→「属性」→「高级系统设置」→「环境变量」,在系统变量中添加
GOROOT(Go 安装路径)和GOPATH(工作目录),并将%GOROOT%\bin添加到 Path 中 - 验证安装:打开 CMD 输入以下命令,显示版本号即为成功
go version

2. 安装 Go 编译器 GoLand
- 官网下载地址:https://www.jetbrains.com/go/download/?section=windows(支持免费试用 30 天)
- 简单配置:安装后新建 Go 项目,选择 GOPATH 路径即可开始编码
3. 第一个 Go 程序(验证环境)
新建hello.go文件,写入以下代码:
package main
import "fmt"
func main() {
fmt.Println("Hello, MySQL!") // 输出问候语,验证环境是否正常
}
运行命令:
go run hello.go
若控制台输出Hello, MySQL!,说明环境搭建完成~

二、Go 基础语法速通(为操作 MySQL 铺垫)
1. 变量赋值与输出
Go 的变量声明支持多种方式,灵活度很高:
package main
import "fmt"
func main() {
var intA = 10 // 自动推导类型
var charA = "a" // 字符串类型
var charB string = "b" // 显式声明类型
intB := 20 // 短变量声明(仅支持函数内)
var intC, intD = 30, 40 // 多变量同时声明
// 三种输出方式对比
fmt.Print("不换行输出:") // 不自动换行
fmt.Printf("intA=%v, intB=%v\n", intA, intB) // 格式化输出(推荐)
fmt.Println("换行输出:", charA, charB, intC, intD) // 自动换行
}
运行结果:

2. 数组与切片(存储查询结果常用)
切片是 Go 中最常用的数据结构,比数组更灵活:
package main
import "fmt"
func main() {
// 数组(固定长度)
level := [3]string{"初级", "中级", "高级"}
fmt.Println("数组:", level[0]) // 访问数组元素
// 切片(动态长度)
var names []string // 声明空切片
num := []int{1, 2, 3, 4, 5} // 初始化带元素的切片
// 切片截取(左闭右开)
slice := num[1:3] // 截取索引1-2的元素,结果:[2,3]
fmt.Println("切片截取:", slice)
// 切片添加元素(返回新切片)
names = append(names, "zhangsan")
fmt.Println("添加元素后:", names) // 结果:[zhangsan]
}

3. 结构体(映射 MySQL 表数据)
操作数据库时,常用结构体存储一行数据:
package main
import "fmt"
type Person struct {
name string
age int
city string
}
func main() {
p1 := Person{
name: "张三",
age: 20,
city: "芜湖",
}
p2 := Person{"李四", 21, "合肥"}
fmt.Println(p1)
fmt.Println(p2)
fmt.Println(p1.name)
p1.age = 22
fmt.Println(p1.age)
fmt.Printf("p1的姓名是:%s,年龄是:%d,城市是:%s\n", p1.name, p1.age, p1.city)
fmt.Printf("p2:%v\n", p2)
}

4. 循环与条件判断(数据处理常用)
package main
import "fmt"
func main() {
// 条件判断(成绩评级)
score := 85
var grade string
if score >= 90 {
grade = "A"
} else if score >= 80 {
grade = "B"
} else if score >= 60 {
grade = "C"
} else {
grade = "F"
}
fmt.Printf("成绩:%d,评级:%s\n", score, grade)
// 循环(遍历切片)
fruits := []string{"苹果", "香蕉", "橙子"}
for index, fruit := range fruits {
fmt.Printf("索引:%d,水果:%s\n", index, fruit)
}
}

三、Go 操作 MySQL 实战(核心部分)
1. 前置准备:创建 MySQL 用户和表
首先在 MySQL 中执行以下 SQL,创建测试用户和表:
-- 创建Go专用操作用户
CREATE USER 'go_rw'@'%' IDENTIFIED BY 'Ud7q_dac8';
-- 授权增删改查权限
GRANT insert,delete,select,update ON maria.* TO 'go_rw'@'%';
-- 切换数据库
USE maria;
-- 创建用户表
CREATE TABLE user_info (
id INT AUTO_INCREMENT PRIMARY KEY, -- 自增主键
name VARCHAR(255) NOT NULL, -- 姓名
age INT NOT NULL -- 年龄
);
2. Go 操作 MySQL 核心代码
步骤 1:安装 MySQL 驱动依赖
打开终端,执行以下命令安装 Go 的 MySQL 驱动:
go get github.com/go-sql-driver/mysql
步骤 2:完整 CRUD 代码实现
package main
import (
"database/sql"
"fmt"
// MySQL驱动(下划线表示只导入不使用,底层会自动注册)
_ "github.com/go-sql-driver/mysql"
)
// UserInfo 结构体映射user_info表
type UserInfo struct {
ID int `db:"id"`
Name string `db:"name"`
Age int `db:"age"`
}
func main() {
// 1. 连接MySQL数据库
// 连接格式:用户名:密码@tcp(IP:端口)/数据库名?charset=utf8mb4
db, err := sql.Open("mysql", "go_rw:Ud7q_dac8@tcp(192.168.184.151:3306)/maria?charset=utf8mb4")
if err != nil {
panic("数据库连接失败:" + err.Error())
}
defer db.Close() // 延迟关闭连接(程序结束前执行)
// 验证连接是否有效
err = db.Ping()
if err != nil {
panic("连接验证失败:" + err.Error())
}
fmt.Println("数据库连接成功!")
// 2. 插入数据(使用预编译防止SQL注入)
insertSQL := "INSERT INTO user_info(name, age) VALUES(?, ?)"
stmt, err := db.Prepare(insertSQL)
if err != nil {
panic("预编译插入SQL失败:" + err.Error())
}
defer stmt.Close()
// 执行插入(参数对应SQL中的?)
result, err := stmt.Exec("John Doe", 25)
if err != nil {
panic("插入数据失败:" + err.Error())
}
insertID, _ := result.LastInsertId()
fmt.Printf("插入成功,新记录ID:%d\n", insertID)
// 3. 查询数据
querySQL := "SELECT id, name, age FROM user_info"
rows, err := db.Query(querySQL)
if err != nil {
panic("查询数据失败:" + err.Error())
}
defer rows.Close()
var users []UserInfo // 存储查询结果
for rows.Next() {
var user UserInfo
// 扫描行数据到结构体(字段顺序需与查询语句一致)
err := rows.Scan(&user.ID, &user.Name, &user.Age)
if err != nil {
panic("数据扫描失败:" + err.Error())
}
users = append(users, user)
}
// 打印查询结果
fmt.Println("\n查询结果:")
for _, u := range users {
fmt.Printf("ID:%d,姓名:%s,年龄:%d\n", u.ID, u.Name, u.Age)
}
// 4. 更新数据
updateSQL := "UPDATE user_info SET name=?, age=? WHERE id=?"
stmtUpdate, err := db.Prepare(updateSQL)
if err != nil {
panic("预编译更新SQL失败:" + err.Error())
}
defer stmtUpdate.Close()
resultUpdate, err := stmtUpdate.Exec("Jane Smith", 30, insertID)
if err != nil {
panic("更新数据失败:" + err.Error())
}
affectedRows, _ := resultUpdate.RowsAffected()
fmt.Printf("\n更新成功,影响行数:%d\n", affectedRows)
// 5. 删除数据
deleteSQL := "DELETE FROM user_info WHERE id=?"
stmtDelete, err := db.Prepare(deleteSQL)
if err != nil {
panic("预编译删除SQL失败:" + err.Error())
}
defer stmtDelete.Close()
resultDelete, err := stmtDelete.Exec(insertID)
if err != nil {
panic("删除数据失败:" + err.Error())
}
deleteRows, _ := resultDelete.RowsAffected()
fmt.Printf("删除成功,影响行数:%d\n", deleteRows)
}
步骤 3:运行代码
将上述代码保存为mysql_demo.go,在终端执行:
go run mysql_demo.go
成功运行后,控制台输出如下:

四、注意事项与常见问题
- 连接失败:检查 MySQL 服务是否启动、IP / 端口是否正确、用户名密码是否匹配、防火墙是否开放 3306 端口
- SQL 注入风险:务必使用
Prepare预编译 +?占位符,避免直接拼接 SQL 字符串 - 字符编码:连接 URL 中添加
charset=utf8mb4,支持 emoji 等特殊字符 - 资源释放:使用
defer关闭数据库连接、语句对象、结果集,避免资源泄露 - 错误处理:实际开发中不要用
panic,应使用if err != nil捕获并处理错误
以上就是 Go 操作 MySQL 的完整教程啦!如果大家在实践中遇到问题,或者想了解更多 Go + 数据库的进阶用法(比如连接池配置、事务处理、ORM 框架使用等),欢迎在评论区留言~ 后续还会分享更多 Go 后端实战技巧,记得关注我的博客哦!



