Go语言实战案例:执行基本的增删改查

在数据库开发中,最基础的操作就是 增(Create)、查(Read)、改(Update)、删(Delete) ,即 CRUD 。

Go 语言通过 database/sql 包和 MySQL 驱动,可以很方便地实现这些功能。

本篇我们将在 上一节"连接 MySQL" 的基础上,扩展实现 完整的 CRUD 案例。


一、准备工作

1. 数据库与表

假设我们已经创建好数据库和表(go_demo 数据库中的 users 表):

sql 复制代码
CREATE DATABASE go_demo;
USE go_demo;

CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50),
    age INT
);

2. 安装 MySQL 驱动

如果还没安装:

go 复制代码
go get -u github.com/go-sql-driver/mysql

二、代码实现

main.go:

go 复制代码
package main

import (
    "database/sql"
    "fmt"
    "log"

    _ "github.com/go-sql-driver/mysql"
)

var db *sql.DB

func initDB() {
    var err error
    dsn := "root:password@tcp(127.0.0.1:3306)/go_demo?charset=utf8mb4&parseTime=True&loc=Local"
    db, err = sql.Open("mysql", dsn)
    if err != nil {
        log.Fatalf("连接数据库失败: %v", err)
    }

    if err := db.Ping(); err != nil {
        log.Fatalf("无法连接到数据库: %v", err)
    }
    fmt.Println("数据库连接成功!")
}

// Create - 插入数据
func createUser(name string, age int) {
    result, err := db.Exec("INSERT INTO users (name, age) VALUES (?, ?)", name, age)
    if err != nil {
        log.Fatalf("插入数据失败: %v", err)
    }
    id, _ := result.LastInsertId()
    fmt.Printf("新增用户成功,ID = %d\n", id)
}

// Read - 查询数据
func getUsers() {
    rows, err := db.Query("SELECT id, name, age FROM users")
    if err != nil {
        log.Fatalf("查询失败: %v", err)
    }
    defer rows.Close()

    fmt.Println("用户列表:")
    for rows.Next() {
        var id, age int
        var name string
        if err := rows.Scan(&id, &name, &age); err != nil {
            log.Fatalf("读取数据失败: %v", err)
        }
        fmt.Printf("ID: %d, 姓名: %s, 年龄: %d\n", id, name, age)
    }
}

// Update - 更新数据
func updateUser(id int, newAge int) {
    result, err := db.Exec("UPDATE users SET age = ? WHERE id = ?", newAge, id)
    if err != nil {
        log.Fatalf("更新数据失败: %v", err)
    }
    rowsAffected, _ := result.RowsAffected()
    fmt.Printf("更新完成,影响行数: %d\n", rowsAffected)
}

// Delete - 删除数据
func deleteUser(id int) {
    result, err := db.Exec("DELETE FROM users WHERE id = ?", id)
    if err != nil {
        log.Fatalf("删除数据失败: %v", err)
    }
    rowsAffected, _ := result.RowsAffected()
    fmt.Printf("删除完成,影响行数: %d\n", rowsAffected)
}

func main() {
    initDB()

    // 增
    createUser("Alice", 25)
    createUser("Bob", 30)

    // 查
    getUsers()

    // 改
    updateUser(1, 26)

    // 查
    getUsers()

    // 删
    deleteUser(2)

    // 查
    getUsers()
}

三、运行结果

假设我们执行:

go 复制代码
go run main.go

输出可能是:

makefile 复制代码
数据库连接成功!
新增用户成功,ID = 1
新增用户成功,ID = 2
用户列表:
ID: 1, 姓名: Alice, 年龄: 25
ID: 2, 姓名: Bob, 年龄: 30
更新完成,影响行数: 1
用户列表:
ID: 1, 姓名: Alice, 年龄: 26
ID: 2, 姓名: Bob, 年龄: 30
删除完成,影响行数: 1
用户列表:
ID: 1, 姓名: Alice, 年龄: 26

四、注意事项

    1. 参数化查询

    使用 ? 占位符,可以有效防止 SQL 注入。

    1. 错误处理

    查询、更新、插入、删除时都应检查 err。

    1. 连接池

    在生产环境中,建议配置连接池:

    scss 复制代码
    db.SetMaxOpenConns(10)
    db.SetMaxIdleConns(5)
    1. 事务支持

    如果多条 SQL 需要保证原子性,应使用 db.Begin() 开启事务。


五、总结

  • • Go 使用 database/sql + MySQL 驱动可以很方便地执行 CRUD 操作。
  • • 推荐使用参数化查询,避免 SQL 注入。
  • • 在生产中,要结合事务、连接池和错误重试机制,确保数据安全性与稳定性。

相关推荐
噢,我明白了1 小时前
java中唯一键和幂等键的应用
java·后端
GreenTea1 小时前
我把 Agent 的 while 循环拆掉了:一种你可能没想到的 Agent 架构
前端·后端·架构
考虑考虑1 小时前
synchronized字符串常量
java·后端·java ee
ZealSinger2 小时前
Go的DefaultClient超时为何总不生效
go·超时·context·net/http·defaultclient
颜进强2 小时前
16 · NestJS LifecycleEvents 生命周期事件:五个钩子、三条边界,和 rag-server 的优雅停机
前端·后端·ai编程
GetcharZp3 小时前
定位不再一个个吐坐标:英伟达 LocateAnything 上手全攻略
后端
郑州光合科技余经理4 小时前
同城电商系统:库存变更怎么同步到订单
java·开发语言·前端·后端·uni-app·php·ai编程
我叫黑大帅4 小时前
Go日志库工程选型与逃逸分析评测报告
后端·面试·go
ShineWinsu6 小时前
对于ProtoBuffer:ProtoBuffer的介绍以及安装
linux·网络·google·协议·序列化·反序列化·protobuffer