56、Go语言基础 - 数据库操作 - Go 操作 MySQL

作者: 温新

分类: 【Go基础】

阅读: 338

时间: 2023-12-05 00:49:48

hi,我是温新

Go 语言中操作 MySQL 数据库通常需要使用第三方库,最常用的库是github.com/go-sql-driver/mysql,它提供了 Go 语言与 MySQL 数据库交互的接口。

准备工作

创建数据表

CREATE TABLE `user_infos` (
    `id` int NOT NULL AUTO_INCREMENT,
    `username` varchar(100) DEFAULT NULL,
    `sex` tinyint NOt NULL DEFAULT 1,
    `email` varchar(260) DEFAULT NULL,
    PRIMARY KEY (`id`)
  ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
  
CREATE TABLE `nations` (
    country varchar(50)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

安装第三方包

go get github.com/go-sql-driver/mysql 
go get github.com/jmoiron/sqlx

连接数据库

sqlx.Open 打开数据库连接。

sqlx.Open(driverName string, dataSourceName string) (*DB, error)
  • driverName(字符串):要使用的数据库驱动程序的名称,例如 "mysql"、"postgres" 等。
  • dataSourceName(字符串):包含数据库连接信息的数据源名称。这个字符串通常包括用户名、密码、数据库地址和名称,如 "username:password@tcp(localhost:3306)/databasename"
package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

func main() {
	// 数据库连接信息
	dsn := "root:123456@tcp(192.168.31.90:3306)/test"
	// 使用 sqlx.Open 打开数据库连接
	db, err := sqlx.Open("mysql", dsn)
	if err != nil {
		fmt.Println("数据库打开失败", err)
		return
	}
	defer db.Close()

	// 测试连接数据库
	err = db.Ping()
	if err != nil {
		fmt.Println("数据库连接失败", err)
		return
	}
	fmt.Println("MySQL 数据库连接成功")
}

insert

db.Execjmoiron/sqlx 包中的一个函数,用于执行 SQ L语句,通常用于执行不需要返回结果集的SQL操作,如插入、更新、删除数据等。

func (db *DB) Exec(query string, args ...interface{}) (sql.Result, error)
  • db: *DB 类型,代表数据库连接对象。
  • query: 字符串,包含要执行的SQL语句,可以包含参数占位符。
  • args: 任意数量的参数,用于替换SQL语句中的占位符。

返回值:

  • sql.Result: 表示执行SQL操作后的结果对象。通常包含受影响的行数等信息。
  • error: 如果执行SQL语句过程中出现错误,将返回一个非空的错误对象。
package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

func main() {
	dsn := "root:123456@tcp(192.168.31.90:3306)/test"
	db, err := sqlx.Open("mysql", dsn)
	if err != nil {
		fmt.Println("数据库打开失败", err)
		return
	}
	defer db.Close()

	err = db.Ping()
	if err != nil {
		fmt.Println("数据库连接失败", err)
		return
	}

	// 插入数据
	insertSQL := "INSERT INTO user_infos (username, sex, email) VALUES (?, ?, ?)"
	res, err := db.Exec(insertSQL, "王美丽", 1, "wangmeili@ziruchu.com")
	if err != nil {
		fmt.Println("数据插入失败", err)
		return
	}

	id, err := res.LastInsertId()
	if err != nil {
		fmt.Println("操作失败, ", err)
		return
	}
	fmt.Println("插入数据成功, ID 为", id)
}

select

Db.Selectjmoiron/sqlx 包中的一个函数,用于执行SQL查询语句,并将结果映射到 Go 结构体切片。

func (db *DB) Select(dest interface{}, query string, args ...interface{}) error
  • db: *DB 类型,代表数据库连接对象。
  • dest: 接口,表示目标,通常是一个空的结构体切片,用于接收查询结果的映射。
  • query: 字符串,包含要执行的SQL查询语句,可以包含参数占位符。
  • args: 任意数量的参数,用于替换SQL语句中的占位符。

返回值:

  • error: 如果执行SQL查询语句过程中出现错误,将返回一个非空的错误对象。
package main

import (
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "github.com/jmoiron/sqlx"
)

func main() {
    // 数据库连接信息
    dsn := "root:123456@tcp(192.168.31.90:3306)/test"

    // 使用 sqlx.Open 打开数据库连接
    db, err := sqlx.Open("mysql", dsn)
    if err != nil {
        fmt.Println("数据库打开失败", err)
        return
    }
    defer db.Close()

    // 测试数据库连接
    err = db.Ping()
    if err != nil {
        fmt.Println("数据库连接失败", err)
        return
    }

    // 查询数据并映射到结构体切片
    var userInfos []UserInfo
    err = db.Select(&userInfos, "SELECT id, username, sex, email FROM user_infos")
    if err != nil {
        fmt.Println("数据查询失败:", err)
        return
    }
    fmt.Println("查询数据成功:", userInfos)

    // 遍历数据并输出
    for _, userInfo := range userInfos {
        fmt.Printf("Id:%d, 姓名:%s, 邮箱:%s\n", userInfo.ID, userInfo.Username, userInfo.Email)
    }
}

// UserInfo 结构体用于映射数据库中的 user_infos 表
type UserInfo struct {
    ID       int    `db:"id"`
    Username string `db:"username"`
    Sex      int    `db:"sex"`
    Email    string `db:"email"`
}

update

package main

import (
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "github.com/jmoiron/sqlx"
)

func main() {
    // 数据库连接信息
    dsn := "root:123456@tcp(192.168.31.90:3306)/test"

    // 使用 sqlx.Open 打开数据库连接
    db, err := sqlx.Open("mysql", dsn)
    if err != nil {
        fmt.Println("数据库打开失败", err)
        return
    }
    defer db.Close()

    // 测试数据库连接
    err = db.Ping()
    if err != nil {
        fmt.Println("数据库连接失败", err)
        return
    }

    // 更新数据
    updateSQL := "UPDATE user_infos SET username = ? WHERE id = ?"
    // 执行更新操作并获取结果
    res, err := db.Exec(updateSQL, "王小丽", 2)
    if err != nil {
        fmt.Println("数据更新失败:", err)
        return
    }

    // 获取受影响的行数
    rowsAffected, err := res.RowsAffected()
    if err != nil {
        fmt.Println("获取受影响的行数失败, ", err)
    }

    fmt.Println("数据更新成功,受影响的行数:", rowsAffected)
}

这个示例连接到数据库,执行一个更新操作,将ID为2的用户的用户名更新为"王小丽"。然后,它获取并输出受影响的行数,以确认更新操作成功。

delete

package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

func main() {
	// 数据库连接信息
	dsn := "root:123456@tcp(192.168.31.90:3306)/test"

	// 使用 sqlx.Open 打开数据库连接
	db, err := sqlx.Open("mysql", dsn)
	if err != nil {
		fmt.Println("数据库打开失败", err)
		return
	}
	defer db.Close()

	// 测试数据库连接
	err = db.Ping()
	if err != nil {
		fmt.Println("数据库连接失败", err)
		return
	}

	// 删除数据
	deleteSQL := "DELETE FROM user_infos WHERE id = ?"
	res, err := db.Exec(deleteSQL, 2)
	if err != nil {
		fmt.Println("数据删除失败:", err)
		return
	}

	// 获取受影响的行数
	row, err := res.RowsAffected()
	if err != nil {
		fmt.Println("获取受影响的行数失败, ", err)
	}

	fmt.Println("数据删除成功,受影响的行数:", row)
}

事务

package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)

func main() {
	// 数据库连接信息
	dsn := "root:123456@tcp(192.168.31.90:3306)/test"

	// 使用 sqlx.Open 打开数据库连接
	db, err := sqlx.Open("mysql", dsn)
	if err != nil {
		fmt.Println("数据库打开失败", err)
		return
	}
	defer db.Close()

	// 测试数据库连接
	err = db.Ping()
	if err != nil {
		fmt.Println("数据库连接失败", err)
		return
	}

	// 开启事务
	tx, err := db.Begin()
	if err != nil {
		fmt.Println("事务启动失败:", err)
		return
	}

	// 用户信息插入
	_, err = tx.Exec("INSERT INTO user_infos (username, sex, email) VALUES (?, ?, ?)", "王丽丽", 1, "wanglili@ziruchu.com")
	if err != nil {
		// 如果插入失败,回滚事务
		tx.Rollback()
		fmt.Println("用户信息写入失败:", err)
		return
	}

	// 国家信息插入
	_, err = tx.Exec("INSERT INTO nations (country) VALUES (?)", "中国")
	if err != nil {
		// 如果插入失败,回滚事务
		tx.Rollback()
		fmt.Println("国家信息插入失败:", err)
		return
	}

	// 提交事务
	err = tx.Commit()
	if err != nil {
		fmt.Println("事务提交失败:", err)
		return
	}

	fmt.Println("事务执行成功")
}

这个示例连接到数据库,开启一个事务,然后插入用户信息和国家信息。如果任何一个插入操作失败,它会回滚整个事务以确保数据一致性。如果两个插入操作都成功,它会提交事务。

请登录后再评论