Go语言使用sqlx操作MySQL

 更新时间:2024年11月14日 11:02:08   作者:左诗右码  
sqlx 包作为一个扩展库,它在 database/sql 的基础上,提供了更高级别的便利,极大地简化了数据库操作,本文章将介绍如何通过sqlx包来操作 MySQL 数据库,感兴趣的可以了解下

Go 语言以其高效和简洁的语法逐渐受到开发者的青睐。在实际开发中,数据库操作是不可避免的任务之一。虽然标准库提供了 database/sql 包来支持数据库操作,但使用起来略显繁琐。

sqlx 包作为一个扩展库,它在 database/sql 的基础上,提供了更高级别的便利,极大地简化了数据库操作。本文章将介绍如何通过 github.com/jmoiron/sqlx 包来操作 MySQL 数据库。

准备工作

首先,确保你的 Go 环境已经搭建完毕,并且 MySQL 数据库已安装并正在运行。接下来,安装 sqlx 包及 MySQL 驱动:

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

连接 MySQL 数据库

在使用数据库之前,我们需要建立与 MySQL 的连接。在 Go 语言中,通常使用一个连接字符串来指定数据库的一些信息。以下是一个示例代码,演示如何连接 MySQL 数据库:

package main

import (
	"fmt"

	_ "github.com/go-sql-driver/mysql" // 一定不能忘记导入数据库驱动
	"github.com/jmoiron/sqlx"
)

var db *sqlx.DB

type User struct {
	ID   int64  `db:"id"`
	Name string `db:"name"`
	Age  int    `db:"age"`
}

func initDB() (err error) {
	dsn := "root:123456@tcp(127.0.0.1:3306)/sql_test?charset=utf8mb4&parseTime=True"
	// 也可以使用 MustConnect 连接不成功就直接 panic
	// db = sqlx.MustConnect("mysql", dsn)
	db, err = sqlx.Connect("mysql", dsn)
	if err != nil {
		fmt.Printf("connect DB failed, err:%v\n", err)
		return
	}
	db.SetMaxOpenConns(20) // 设置数据库连接池的最大连接数
	db.SetMaxIdleConns(10) // 设置数据库连接池的最大空闲连接数
	return
}

在这个例子中,请替换为你自己的MySQL 配置。

数据库操作

1. 创建表

接下来,让我们创建一个示例表。我们可以使用 Exec 方法执行 SQL 语句来创建表。

func CreateTable(db *sqlx.DB) (err error) {
	// 写SQL语句
	sqlStr := `create table if not exists users (
		id bigint primary key auto_increment,
		name varchar(20),
		age int default 1
	);`
	_, err = db.Exec(sqlStr)

	return err
}

main 函数中调用 CreateTable(db),以确保在连接后创建表。

2. 插入数据

// 插入用户并获取 ID
func insertUser(db *sqlx.DB, name string, age int) (int64, error) {
	result, err := db.Exec("INSERT INTO users(name, age) VALUES(?, ?)", name, age)
	if err != nil {
		return 0, err
	}

	id, err := result.LastInsertId()
	if err != nil {
		return 0, err
	}
	return id, nil
}

3. 查询数据

// 查询单条用户记录
func getUser(db *sqlx.DB, id int64) (*User, error) {
	var user User
	err := db.Get(&user, "SELECT * FROM users WHERE id=?", id)
	if err != nil {
		return nil, err
	}
	return &user, nil
}

// 查询所有用户记录
func getAllUsers(db *sqlx.DB, id int64) ([]User, error) {
	var users []User
	err := db.Select(&users, "SELECT * FROM users where id > ?", id)
	if err != nil {
		return nil, err
	}
	return users, nil
}

4. 更新数据

// 更新用户信息
func updateUser(db *sqlx.DB, id int64, name string, age int) (int64, error) {
	result, err := db.Exec("UPDATE users SET name=?, age=? WHERE id=?", name, age, id)
	if err != nil {
		return 0, err
	}
	rowsAffected, err := result.RowsAffected()
	if err != nil {
		return 0, err
	}
	return rowsAffected, nil
}

5. 删除数据

// 删除用户记录
func deleteUser(db *sqlx.DB, id int64) (int64, error) {
	result, err := db.Exec("DELETE FROM users WHERE id=?", id)
	if err != nil {
		return 0, err
	}
	rowsAffected, err := result.RowsAffected()
	if err != nil {
		return 0, err
	}
	return rowsAffected, nil
}

6. 使用命名参数来操作

// 使用命名参数插入用户
func insertUserNamed(db *sqlx.DB, name string, age int) (int64, error) {
	query := `INSERT INTO users(name, age) VALUES(:name, :age)`
	result, err := db.NamedExec(query, map[string]interface{}{
		"name": name,
		"age":  age,
	})
	if err != nil {
		return 0, err
	}
	id, err := result.LastInsertId()
	if err != nil {
		return 0, err
	}
	return id, nil
}

// 使用命名参数查询用户
func getUsersNamed(db *sqlx.DB, name string) ([]User, error) {
	query := `SELECT * FROM users WHERE name = :name`
	var users []User
	rows, err := db.NamedQuery(query, map[string]interface{}{
		"name": name,
	})
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	for rows.Next() {
		var user User
		err := rows.StructScan(&user)
		if err != nil {
			fmt.Printf("scan failed, err:%v\n", err)
			continue
		}
		users = append(users, user)
	}

	return users, nil
}

7. 测试一下代码

func Run() {
	// 初始化数据库
	err := initDB()
	if err != nil {
		fmt.Printf("init DB failed, err:%v\n", err)
		return
	}
	defer db.Close() // 注意这行代码要写在上面err判断的下面

	// 创建表
	err = CreateTable(db)
	if err != nil {
		fmt.Printf("create table failed, err:%v\n", err)
		return
	}

	// 插入数据
	id, err := insertUser(db, "Alex", 18)
	if err != nil {
		fmt.Printf("insert user failed, err:%v\n", err)
		return
	}
	fmt.Println("insert success, the id is:", id)

	// 查询单条数据
	user, err := getUser(db, id)
	if err != nil {
		fmt.Printf("get user failed, err:%v\n", err)
		return
	}

	fmt.Printf("user:%#v\n", user)

	// 查询多条数据
	users, err := getAllUsers(db, 0)
	if err != nil {
		fmt.Printf("get all users failed, err:%v\n", err)
		return
	}

	fmt.Printf("users:%#v\n", users)

	// 更新数据
	rowsAffected, err := updateUser(db, id, "Alex", 20)
	if err != nil {
		fmt.Printf("update user failed, err:%v\n", err)
		return
	}

	fmt.Println("update success, affected rows:", rowsAffected)

	// 删除数据
	rowsAffected, err = deleteUser(db, id)
	if err != nil {
		fmt.Printf("delete user failed, err:%v\n", err)
		return
	}

	fmt.Println("delete success, affected rows:", rowsAffected)

	// 使用命名参数插入数据
	id, err = insertUserNamed(db, "Alex", 19)
	if err != nil {
		fmt.Printf("insert user named failed, err:%v\n", err)
		return
	}

	fmt.Println("insert named success, the id is:", id)

	// 使用命名参数查询数据
	users, err = getUsersNamed(db, "Alex")
	if err != nil {
		fmt.Printf("get users named failed, err:%v\n", err)
		return
	}

	fmt.Printf("users named:%#v\n", users)

	fmt.Println("exec SQL success")
}

我们可以看到,使用 sqlx 还是要比 database/sql 要简洁许多。

总结

通过 sqlx 包,我们可以更简单地在 Go 中与 MySQL 数据库进行交互,减少了样板代码并提高了代码的可读性。

到此这篇关于Go语言使用sqlx操作MySQL的文章就介绍到这了,更多相关Go sqlx操作MySQL内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用Go语言编写简洁代码的最佳实践

    使用Go语言编写简洁代码的最佳实践

    简洁的代码对于创建可维护、可阅读和高效的软件至关重要,Go 是一种强调简单和代码整洁的语言,在本文中,我们将结合代码示例,探讨编写简洁 Go 代码的最佳实践,需要的朋友可以参考下
    2023-09-09
  • go code review 代码调试

    go code review 代码调试

    这篇文章主要为大家介绍了go code review 代码调试方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • go Antlr重构脚本解释器实现示例

    go Antlr重构脚本解释器实现示例

    这篇文章主要为大家介绍了go Antlr重构脚本解释器实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • 掌握Golang中的select语句实现并发编程

    掌握Golang中的select语句实现并发编程

    Golang中的select语句用于在多个通道间选择可读或可写的操作,并阻塞等待其中一个通道进行操作。可以用于实现超时控制、取消和中断操作等。同时,select语句支持default分支,用于在没有任何通道可操作时执行默认操作
    2023-04-04
  • go语言Timer计时器的用法示例详解

    go语言Timer计时器的用法示例详解

    Go语言的标准库里提供两种类型的计时器Timer和Ticker。这篇文章通过实例代码给大家介绍go语言Timer计时器的用法,代码简单易懂,感兴趣的朋友跟随小编一起看看吧
    2020-05-05
  • Golang使用Gin处理下载文件请求返回

    Golang使用Gin处理下载文件请求返回

    在Go语言中,使用Gin框架实现文件下载功能相对简单,本文给大家展示一个简单的示例,演示如何使用Gin来处理文件下载请求,文中通过代码示例给大家介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • Go语言遍历目录的三种方法举例

    Go语言遍历目录的三种方法举例

    学习io之后,尤其是文件操作,我们就可以遍历给定的目录了,这篇文章主要给大家介绍了关于Go语言遍历目录的三种方法,分别是ioutil.ReadDir、filepath.Walk以及filepath.Glob,需要的朋友可以参考下
    2023-11-11
  • Go语言error的设计理念及背景演化详解

    Go语言error的设计理念及背景演化详解

    这篇文章主要为大家介绍了Go语言error的设计理念及背景演化详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • 详解golang中发送http请求的几种常见情况

    详解golang中发送http请求的几种常见情况

    这篇文章主要介绍了详解golang中发送http请求的几种常见情况,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • golang端口占用检测的使用

    golang端口占用检测的使用

    这篇文章主要介绍了golang端口占用检测的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03

最新评论