golang连接mysql数据库实现增删改查

本文介绍如何使用Go语言通过database/sql包操作MySQL数据库,包括连接数据库、执行插入、查询、更新和删除操作,并提供了完整的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 数据库连接使用datebase/sql Open函数进行连接
 

 代码如下  

db, err := sql.Open("mysql", "user:password@tcp(localhost:5555)/dbname?charset=utf8")
其中连接参数可以有如下几种形式:

user@unix(/path/to/socket)/dbname?charset=utf8
user:password@tcp(localhost:5555)/dbname?charset=utf8
user:password@/dbname
user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname

通常我们都用第二种。

插入操作
 

 代码如下  
stmt, err := db.Prepare(`INSERT user (user_name,user_age,user_sex) values (?,?,?)`)
checkErr(err)
res, err := stmt.Exec("tony", 20, 1)
checkErr(err)
id, err := res.LastInsertId()
checkErr(err)
fmt.Println(id)

这里使用结构化操作,不推荐使用直接拼接sql语句的方法。

查询操作
 

 代码如下  
rows, err := db.Query("SELECT * FROM user")
checkErr(err)
 
for rows.Next() {
    var userId int
    var userName string
    var userAge int
    var userSex int
    rows.Columns()
    err = rows.Scan(&userId, &userName, &userAge, &userSex)
    checkErr(err)
    fmt.Println(userId)
    fmt.Println(userName)
    fmt.Println(userAge)
    fmt.Println(userSex)
}

这里查询的方式使用声明4个独立变量userId、userName、userAge、userSex来保存查询出来的每一行的值。在实际开发中通常会封装数据库的操作,对这样的查询通常会考虑返回字典类型。

 

 代码如下  

//构造scanArgs、values两个数组,scanArgs的每个值指向values相应值的地址
columns, _ := rows.Columns()
scanArgs := make([]interface{}, len(columns))
values := make([]interface{}, len(columns))
for i := range values {
    scanArgs[i] = &values[i]
}
 
for rows.Next() {
    //将行数据保存到record字典
    err = rows.Scan(scanArgs...)
    record := make(map[string]string)
    for i, col := range values {
        if col != nil {
            record[columns[i]] = string(col.([]byte))
        }
    }
    fmt.Println(record)
}
修改操作

stmt, err := db.Prepare(`UPDATE user SET user_age=?,user_sex=? WHERE user_id=?`)
checkErr(err)
res, err := stmt.Exec(21, 2, 1)
checkErr(err)
num, err := res.RowsAffected()
checkErr(err)
fmt.Println(num)
删除操作


stmt, err := db.Prepare(`DELETE FROM user WHERE user_id=?`)
checkErr(err)
res, err := stmt.Exec(1)
checkErr(err)
num, err := res.RowsAffected()
checkErr(err)
fmt.Println(num)

修改和删除操作都比较简单,同插入数据类似,只是使用RowsAffected来获取影响的数据行数。 

完整代码

 代码如下  

package main
 
import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
)
 
func main() {
    insert()
}
 
//插入demo
func insert() {
    db, err := sql.Open("mysql", "root:@/test?charset=utf8")
    checkErr(err)
 
    stmt, err := db.Prepare(`INSERT user (user_name,user_age,user_sex) values (?,?,?)`)
    checkErr(err)
    res, err := stmt.Exec("tony", 20, 1)
    checkErr(err)
    id, err := res.LastInsertId()
    checkErr(err)
    fmt.Println(id)
}
 
//查询demo
func query() {
    db, err := sql.Open("mysql", "root:@/test?charset=utf8")
    checkErr(err)
 
    rows, err := db.Query("SELECT * FROM user")
    checkErr(err)
 
    //普通demo
    //for rows.Next() {
    //    var userId int
    //    var userName string
    //    var userAge int
    //    var userSex int
 
    //    rows.Columns()
    //    err = rows.Scan(&userId, &userName, &userAge, &userSex)
    //    checkErr(err)
 
    //    fmt.Println(userId)
    //    fmt.Println(userName)
    //    fmt.Println(userAge)
    //    fmt.Println(userSex)
    //}
 
    //字典类型
    //构造scanArgs、values两个数组,scanArgs的每个值指向values相应值的地址
    columns, _ := rows.Columns()
    scanArgs := make([]interface{}, len(columns))
    values := make([]interface{}, len(columns))
    for i := range values {
        scanArgs[i] = &values[i]
    }
 
    for rows.Next() {
        //将行数据保存到record字典
        err = rows.Scan(scanArgs...)
        record := make(map[string]string)
        for i, col := range values {
            if col != nil {
                record[columns[i]] = string(col.([]byte))
            }
        }
        fmt.Println(record)
    }
}
 
//更新数据
func update() {
    db, err := sql.Open("mysql", "root:@/test?charset=utf8")
    checkErr(err)
 
    stmt, err := db.Prepare(`UPDATE user SET user_age=?,user_sex=? WHERE user_id=?`)
    checkErr(err)
    res, err := stmt.Exec(21, 2, 1)
    checkErr(err)
    num, err := res.RowsAffected()
    checkErr(err)
    fmt.Println(num)
}
 
//删除数据
func remove() {
    db, err := sql.Open("mysql", "root:@/test?charset=utf8")
    checkErr(err)
 
    stmt, err := db.Prepare(`DELETE FROM user WHERE user_id=?`)
    checkErr(err)
    res, err := stmt.Exec(1)
    checkErr(err)
    num, err := res.RowsAffected()
    checkErr(err)
    fmt.Println(num)
}
 
func checkErr(err error) {
    if err != nil {
        panic(err)
    }
}

小结

整体上来说都比较简单,就是查询那边使用字典来存储返回数据比较复杂一些。既然说到数据库连接,通常应用中都会使用连接池来减少连接开销,关于连接池下次整理一下再放上来

<think>好的,用户让我用Golang代码写一个MySQL增删改查示例。首先,我得确认用户的需求是什么。他们可能刚开始学习Golang,或者想了解如何用Golang操作数据库。需要提供一个简单明了的例子,涵盖基本的CRUD操作。 首先,我需要考虑如何连接MySQLGolang中常用的驱动是database/sql包配合具体的驱动,比如go-sql-driver/mysql。用户可能不知道需要先导入这个驱动,所以得提醒他们安装。 然后,建立数据库连接。代码结构通常是先导入必要的包,然后使用sql.Open()函数,参数是数据源名称。需要说明DSN的格式,比如用户名、密码、地址、数据库名和参数。 接下来是创建表。用户可能已经有表了,但为了示例完整,应该包含创建表的语句,比如CREATE TABLE IF NOT EXISTS。这样他们可以直接运行代码而不会出错。 然后是插入数据的例子。使用Exec方法执行INSERT语句,可能需要处理自增ID的获取。这里需要注意错误处理,每个操作后都要检查错误,并给出提示。 查询部分,使用Query或QueryRow,然后扫描结果到结构体或者变量中。需要展示如何遍历多行结果,使用rows.Next()循环。 更新和删除操作也是类似的,用Exec执行语句,处理返回的结果和错误。需要提醒用户注意WHERE条件,避免全表更新或删除。 最后,整合所有步骤,展示一个完整的示例代码。同时需要指出可能需要注意的地方,比如关闭连接、SQL注入的问题(虽然这里用参数化查询避免了),以及错误处理的重要性。 可能用户对预处理语句不太熟悉,但示例中已经用了参数化,所以可以不用深入。另外,需要确保代码的简洁性,方便用户理解。可能还需要提到数据库驱动的注册,用匿名导入的方式,因为很多新手可能会忽略这一点。 总结一下,步骤是:安装驱动、连接数据库、建表、增删改查操作、关闭资源。每个部分都要用注释说明,代码结构清晰。最后检查代码是否有明显错误,比如拼写错误,或者DSN格式是否正确。以下</think>是一个使用 Go 语言实现 MySQL 增删改查(CRUD)的示例代码,包含详细注释说明: ```go package main import ( "database/sql" "fmt" "log" _ "github.com/go-sql-driver/mysql" // 导入 MySQL 驱动 ) // 定义用户结构体 type User struct { ID int Name string Age int } var db *sql.DB func main() { // 初始化数据库连接 err := initDB() if err != nil { log.Fatal(err) } defer db.Close() // 创建用户 id, err := createUser("张三", 25) if err != nil { log.Fatal(err) } fmt.Printf("创建用户ID: %d\n", id) // 查询用户 user, err := getUser(id) if err != nil { log.Fatal(err) } fmt.Printf("查询用户: %+v\n", user) // 更新用户 rowsAffected, err := updateUser(id, "李四", 30) if err != nil { log.Fatal(err) } fmt.Printf("更新影响行数: %d\n", rowsAffected) // 删除用户 rowsAffected, err = deleteUser(id) if err != nil { log.Fatal(err) } fmt.Printf("删除影响行数: %d\n", rowsAffected) } // 初始化数据库连接 func initDB() error { var err error // 格式:用户名:密码@tcp(地址:端口)/数据库名?参数 dsn := "root:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True" db, err = sql.Open("mysql", dsn) if err != nil { return err } // 测试连接是否成功 err = db.Ping() if err != nil { return err } // 创建用户表 createTableSQL := ` CREATE TABLE IF NOT EXISTS users( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, age INT NOT NULL )` _, err = db.Exec(createTableSQL) return err } // 创建用户 func createUser(name string, age int) (int64, error) { result, err := db.Exec("INSERT INTO users(name, age) VALUES(?, ?)", name, age) if err != nil { return 0, err } return result.LastInsertId() // 返回插入的ID } // 查询单个用户 func getUser(id int64) (*User, error) { user := &User{} err := db.QueryRow("SELECT id, name, age FROM users WHERE id = ?", id). Scan(&user.ID, &user.Name, &user.Age) if err != nil { return nil, err } return user, nil } // 更新用户 func updateUser(id int64, newName string, newAge int) (int64, error) { result, err := db.Exec("UPDATE users SET name = ?, age = ? WHERE id = ?", newName, newAge, id) if err != nil { return 0, err } return result.RowsAffected() // 返回影响行数 } // 删除用户 func deleteUser(id int64) (int64, error) { result, err := db.Exec("DELETE FROM users WHERE id = ?", id) if err != nil { return 0, err } return result.RowsAffected() } ``` 使用说明: 1. 需要先安装 MySQL 驱动: ```bash go get -u github.com/go-sql-driver/mysql ``` 2. 需要提前创建数据库(示例中使用 `testdb`): ```sql CREATE DATABASE testdb; ``` 3. 代码中的连接参数需要根据实际情况修改: ```go dsn := "root:password@tcp(127.0.0.1:3306)/testdb?charset=utf8mb4&parseTime=True" ``` 代码特点: - 使用标准库 `database/sql` - 参数化查询防止 SQL 注入 - 包含完整的 CRUD 操作 - 使用结构体映射数据 - 包含错误处理 - 自动创建数据表 注意事项: 1. 确保 MySQL 服务已启动 2. 数据库用户需要有相应权限 3. 生产环境需要添加更完善的错误处理 4. 建议使用连接池配置(代码中 `db.SetMaxOpenConns()` 等) 5. 复杂查询可以使用 sqlx 等扩展库简化操作 这个示例展示了基本的数据库操作流程,实际开发中可以根据需要添加事务处理、预处理语句等高级功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值