【Go】 使用 github.com/jmoiron/sqlx 进行 【数据库操作】【mysql】

介绍

在 Go 语言中,标准库提供的 database/sql 包可以与各种数据库进行交互,但在某些情况下,使用更高层的库如 sqlx 可以使代码更加简洁和易于维护。sqlx 是一个扩展了 database/sql 的库,提供了更多便捷的功能,比如命名参数、结构体扫描等。本文将介绍如何使用 sqlx 与 MySQL 数据库进行基本的操作,包括连接数据库、执行查询、插入、更新和删除记录。

安装

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

连接数据库

使用 sqlx 连接到 MySQL 数据库的代码示例如下:

package main

import (
    "log"

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

func main() {
    // 数据库连接字符串
    dsn := "username:password@tcp(localhost:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := sqlx.Connect("mysql", dsn)
    if err != nil {
        log.Fatalln(err)
    }
    defer db.Close()

    log.Println("成功连接到数据库")
}

在连接字符串中,需要根据自己的 MySQL 配置替换 usernamepassworddbname

基本的 CRUD 操作

1. 创建(Insert)

下面是使用 sqlx 插入数据的示例:

type User struct {
    ID   int64  `db:"id"`   // 注意 db 标签
    Name string `db:"name"`
    Age  int    `db:"age"`
}

func createUser(db *sqlx.DB, name string, age int) (int64, error) {
    query := "INSERT INTO users (name, age) VALUES (?, ?)"
    result, err := db.Exec(query, name, age)
    if err != nil {
        return 0, err
    }
    id, err := result.LastInsertId()
    return id, err
}
2. 读取(Select)

获取数据同样很简单,可以使用 GetSelect 方法。

获取单个用户信息:

func getUser(db *sqlx.DB, id int64) (*User, error) {
    user := &User{}
    query := "SELECT id, name, age FROM users WHERE id = ?"
    err := db.Get(user, query, id)
    if err != nil {
        return nil, err
    }
    return user, nil
}

获取所有用户:

func getAllUsers(db *sqlx.DB) ([]User, error) {
    var users []User
    query := "SELECT id, name, age FROM users"
    err := db.Select(&users, query)
    return users, err
}
3. 更新(Update)

更新数据使用 Exec 方法:

func updateUser(db *sqlx.DB, id int64, name string, age int) error {
    query := "UPDATE users SET name = ?, age = ? WHERE id = ?"
    _, err := db.Exec(query, name, age, id)
    return err
}
4. 删除(Delete)
func deleteUser(db *sqlx.DB, id int64) error {
    query := "DELETE FROM users WHERE id = ?"
    _, err := db.Exec(query, id)
    return err
}

使用事务

在处理多个数据库操作时,使用事务可以确保数据的一致性。例如,可以在创建用户的同时记录日志:

func createUserWithTransaction(db *sqlx.DB, name string, age int) error {
    tx := db.MustBegin()

    // 插入用户
    _, err := tx.Exec("INSERT INTO users (name, age) VALUES (?, ?)", name, age)
    if err != nil {
        tx.Rollback()
        return err
    }

    // 记录日志(假设有一个日志表)
    _, err = tx.Exec("INSERT INTO user_logs (user_name) VALUES (?)", name)
    if err != nil {
        tx.Rollback()
        return err
    }

    return tx.Commit()
}

错误处理

if err == sql.ErrNoRows {
    log.Println("没有找到用户")
} else if err != nil {
    log.Fatal(err)
}

封装工具类CURD

import (
	"core"
	"fmt"
	"log"
	"strconv"
	"strings"
	"time"

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

func InitClientMysql(auth core.Auth, dbname string) *sqlx.DB {
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", auth.Name, auth.Pwd, auth.Host, 3306, dbname)
	client, err := sqlx.Connect("mysql", dsn)
	if err != nil {
		log.Println(fmt.Sprintf("connect to %s %s failed", auth.Host, dbname))
		log.Println(err)
	}
	client.SetMaxOpenConns(25)
	client.SetMaxIdleConns(25)
	client.SetConnMaxIdleTime(15 * time.Minute)
	err = client.Ping()
	log.Println(fmt.Sprintf("connect to %s %s successfully", auth.Host, dbname))
	return client
}

func Insert(client *sqlx.DB, tablename string, param map[string]interface{}) int64 {
	var keys []string
	var values []string
	for key, value := range param {
		keys = append(keys, key)
		switch value.(type) {
		case int, int64, int32:
			values = append(values, strconv.Itoa(value.(int)))
		case string:
			values = append(values, value.(string))
		case float32, float64:
			values = append(values, strconv.FormatFloat(value.(float64), 'f', -1, 64))
		}

	}
	fileValue := "'" + strings.Join(values, "','") + "'"
	fileds := "`" + strings.Join(keys, "`,`") + "`"
	isql := fmt.Sprintf("INSERT INTO %v (%v) VALUES (%v)", tablename, fileds, fileValue)
	log.Println(isql)
	result, err := client.Exec(isql)
	if err != nil {
		log.Println(err)
	}
	s, err := result.LastInsertId()
	log.Println(s)
	return s
}

func Update(client *sqlx.DB, tablename string, where string, param map[string]interface{}) int {
	var setValue []string
	for key, value := range param {
		switch value.(type) {
		case int, int64, int32:
			set := fmt.Sprintf("%v = %v", key, value.(int))
			setValue = append(setValue, set)
		case string:
			set := fmt.Sprintf("%v = '%v'", key, value.(string))
			setValue = append(setValue, set)
		case float32, float64:
			set := fmt.Sprintf("%v = '%v'", key, strconv.FormatFloat(value.(float64), 'f', -1, 64))
			setValue = append(setValue, set)
		}
	}
	setData := strings.Join(setValue, ",")
	usql := fmt.Sprintf("UPDATE %v SET %v WHERE %v", tablename, setData, where)
	log.Println(usql)
	result, err := client.Exec(usql)
	if err != nil {
		log.Println(err)
	}
	s, _ := result.RowsAffected()
	return int(s)
}

func Delete(client *sqlx.DB, tablename string, param string) int64 {
	dsql := fmt.Sprintf("DELETE FROM %v WHERE %v", tablename, param)
	log.Println(dsql)
	result, err := client.Exec(dsql)
	if err != nil {
		log.Println(err)
	}
	s, _ := result.RowsAffected()
	return s
}

func WaitNew(client *sqlx.DB, query string, wait int) {
	var num int
	log.Println(query)
	for {
		err := client.QueryRow(query).Scan(&num)
		if err != nil {
			log.Println(err)
		}
		log.Println(num)
		if num > 0 {
			log.Println(fmt.Sprintf("wait %d Second", wait*10))
			time.Sleep(time.Duration(wait*10) * time.Second)
		} else {
			break
		}
	}
}


 

猜你喜欢

转载自blog.csdn.net/jhgj56/article/details/143110795