【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

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

成功运行后,控制台输出如下:

四、注意事项与常见问题

  1. 连接失败:检查 MySQL 服务是否启动、IP / 端口是否正确、用户名密码是否匹配、防火墙是否开放 3306 端口
  2. SQL 注入风险:务必使用Prepare预编译 +?占位符,避免直接拼接 SQL 字符串
  3. 字符编码:连接 URL 中添加charset=utf8mb4,支持 emoji 等特殊字符
  4. 资源释放:使用defer关闭数据库连接、语句对象、结果集,避免资源泄露
  5. 错误处理:实际开发中不要用panic,应使用if err != nil捕获并处理错误

以上就是 Go 操作 MySQL 的完整教程啦!如果大家在实践中遇到问题,或者想了解更多 Go + 数据库的进阶用法(比如连接池配置、事务处理、ORM 框架使用等),欢迎在评论区留言~ 后续还会分享更多 Go 后端实战技巧,记得关注我的博客哦!

Tags:

发表回复

Your email address will not be published. Required fields are marked *.

*
*