go

使用go管理mysql

mysql环境准备

我的测试mysql是放在k8s集群中的,放开了nodeport,使用navicat连接。

创建数据库

create database golang

创建表

CREATE TABLE user (
  id INTEGER PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR (20),
  password VARCHAR (20)
)

插入数据

INSERT INTO user (name, password) VALUES ("tom", "123")
INSERT INTO user (name, password) VALUES ("jerry", "456")

file

安装mysql驱动

sql 包必须与数据库驱动程序结合使用。有关驱动程序列表,请参阅 https://golang.org/s/sqldrivers
这里使用的是go-sql-driver/mysql包。

go get -u github.com/go-sql-driver/mysql

目录结构

file

连接数据库

连接数据库需要使用database/sql包,地址是:
https://pkg.go.dev/database/sql
方法如下:

func Open(driverName, dataSourceName string) (*DB, error)
func (db *DB) Close() error
func (db *DB) Ping() error

init.go

代码如下:

package initdb

import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "log"
    "time"
)

var Pool *sql.DB // 创建一个连接池

func main() {
    // 数据库连接信息
    dbHost := "1.2.3.4"
    dbPort := 12345
    dbUser := "root"
    dbPass := "root"
    dbName := "golang" // 替换为你的数据库名称

    // 构建连接字符串
    connStr := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True", dbUser, dbPass, dbHost, dbPort, dbName)

    // 连接数据库
    Pool, err = sql.Open("mysql", connStr)

    // 设置最大连接时长。小于等于0表示没有限制
    Pool.SetConnMaxLifetime(time.Minute * 3)
    // 设置最大连接数
    Pool.SetMaxOpenConns(10)
    // 设置闲置连接数
    Pool.SetMaxIdleConns(10)

    if err != nil {
        log.Fatal(err)
    }

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

file

查询数据

查询可以分为单行查询和多行查询。使用的方法如下:

func (db *DB) Query(query string, args ...any) (*Rows, error)
// Query 执行返回行的查询,通常为 SELECT。args 用于查询中的任何占位符参数。
func (db *DB) QueryContext(ctx context.Context, query string, args ...any) (*Rows, error)
// 指定上下文查询
func (db *DB) QueryRow(query string, args ...any) *Row
// QueryRow 执行预计最多返回一行的查询。QueryRow 始终返回非 nil 值。错误将推迟到调用 Row 的 Scan 方法之前。如果查询未选择任何行,则 *Row's Scan 将返回 ErrNoRows。否则,*行扫描将扫描选定的第一行并丢弃其余行。
func (db *DB) QueryRowContext(ctx context.Context, query string, args ...any) *Row
// 指定上下文查询单行

单行查询

select.go

package selectdb

import (
    "fmt"
    initdb "mysql/initdb"
)

type user struct {
    id       int
    name     string
    password string
}

func Select() {
    sqlCommand := "select * from user where id = ?"
    var u user
    err := initdb.Pool.QueryRow(sqlCommand, 1).Scan(&u.id, &u.name, &u.password)
    if err != nil {
        fmt.Printf("scan failed, err:%v\n", err)
        return
    }
    fmt.Printf("id:%d,name:%s,password:%s\n", u.id, u.name, u.password)
    defer initdb.Pool.Close()
}

main.go

package main

import (
    "fmt"
    "mysql/initdb"
    "mysql/selectdb"
)

func main() {
    err := initdb.InitDB()
    if err != nil {
        fmt.Printf("数据库连接失败, err:%v\n", err)
        return
    } else {
        fmt.Printf("数据库连接成功\n")
    }
    selectdb.Select()
}

file

多行查询

func (rs *Rows) Next() bool
// Next 准备下一个结果行,以便使用 Scan 方法进行读取。成功时返回 true,如果没有下一个结果行或准备时发生错误,则返回 false。应查阅 Err 以区分这两种情况。每次对 Scan 的调用,即使是第一次调用,都必须先调用 Next。
func (rs *Rows) Scan(dest ...any) error
// Scan 将当前行中的列复制到 dest 指向的值中。dest 中的值数必须与 Rows 中的列数相同。Scan 将从数据库中读取的列转换为 sql 包提供的常见 Go 类型和特殊类型。

multiselect.go

package selectdb

import (
    "fmt"
    initdb "mysql/initdb"
)

func MultiSelect() {
    sqlCommand := "select * from user where id > ?"
    var u user
    results, err := initdb.Pool.Query(sqlCommand, 0)
    if err != nil {
        fmt.Printf("query failed, err:%v\n", err)
        return
    }
    // 关闭results,释放持有的数据库连接资源
    defer results.Close()

    // 循环读取结果
    for results.Next() {
        err = results.Scan(&u.id, &u.name, &u.password)
        if err != nil {
            fmt.Printf("scan failed, err:%v\n", err)
            return
        }
        fmt.Printf("id:%d,name:%s,password:%s\n", u.id, u.name, u.password)
    }
}

main.go

func main() {
    err := initdb.InitDB()
    if err != nil {
        fmt.Printf("数据库连接失败, err:%v\n", err)
        return
    } else {
        fmt.Printf("数据库连接成功\n")
    }
    //selectdb.Select()
    selectdb.MultiSelect()
}

file

插入数据

使用的方法如下:

func (db *DB) Exec(query string, args ...any) (Result, error)
// Exec 在不返回任何行的情况下执行查询。args 用于查询中的任何占位符参数。
func (db *DB) ExecContext(ctx context.Context, query string, args ...any) (Result, error)
// 指定上下文
type Result interface {
    // LastInsertId returns the integer generated by the database
    // in response to a command. Typically this will be from an
    // "auto increment" column when inserting a new row. Not all
    // databases support this feature, and the syntax of such
    // statements varies.
    LastInsertId() (int64, error)

    // RowsAffected returns the number of rows affected by an
    // update, insert, or delete. Not every database or database
    // driver may support this.
    RowsAffected() (int64, error)
}

insert.go

package insertdb

import (
    "fmt"
    "log"
    initdb "mysql/initdb"
)

func InsertDB() {
    sqlCommand := "insert into user(name, password) values(?, ?)"
    result, err := initdb.Pool.Exec(sqlCommand, "ikun", "2nianban")
    if err != nil {
        fmt.Printf("insert failed, err:%v\n", err)
        return
    }
    rows, err := result.LastInsertId()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("insert success, id is: %d\n", rows)
    defer initdb.Pool.Close()
}

main.go

func main() {
    err := initdb.InitDB()
    if err != nil {
        fmt.Printf("数据库连接失败, err:%v\n", err)
        return
    } else {
        fmt.Printf("数据库连接成功\n")
    }
    //selectdb.Select()
    //selectdb.MultiSelect()
    insertdb.InsertDB()
}

file

file

删除数据

删除数据也是用的Exec方法。

delete.go

package deletedb

import (
    "fmt"
    initdb "mysql/initdb"
)

func DeleteDB() {
    sqlCommand := "delete from user where id = ?"
    result, err := initdb.Pool.Exec(sqlCommand, 1)
    if err != nil {
        fmt.Printf("delete failed, err:%v\n", err)
        return
    }
    rows, err := result.RowsAffected()
    if err != nil {
        fmt.Printf("delete failed, err:%v\n", err)
        return
    }
    fmt.Printf("delete success, affected rows:%d\n", rows)
    defer initdb.Pool.Close()
}

main.go

func main() {
    err := initdb.InitDB()
    if err != nil {
        fmt.Printf("数据库连接失败, err:%v\n", err)
        return
    } else {
        fmt.Printf("数据库连接成功\n")
    }
    //selectdb.Select()
    //selectdb.MultiSelect()
    //insertdb.InsertDB()
    deletedb.DeleteDB()
}

file

file

更新数据

更新数据也是用的Exec方法

update.go

package updatedb

import (
    "fmt"
    initdb "mysql/initdb"
)

func UpdateDB() {
    sqlCommand := "update user set name = ? where id = ?"
    result, err := initdb.Pool.Exec(sqlCommand, "basketball", 2)
    if err != nil {
        fmt.Printf("update failed, err:%v\n", err)
        return
    }
    rows, err := result.RowsAffected()
    if err != nil {
        fmt.Printf("update failed, err:%v\n", err)
        return
    }
    fmt.Printf("update success, affected rows:%d\n", rows)
    defer initdb.Pool.Close()
}

main.go

func main() {
    err := initdb.InitDB()
    if err != nil {
        fmt.Printf("数据库连接失败, err:%v\n", err)
        return
    } else {
        fmt.Printf("数据库连接成功\n")
    }
    //selectdb.Select()
    //selectdb.MultiSelect()
    //insertdb.InsertDB()
    //deletedb.DeleteDB()
    updatedb.UpdateDB()
}

file

file

分类: go
0 0 投票数
文章评分
订阅评论
提醒
guest

0 评论
最旧
最新 最多投票
内联反馈
查看所有评论

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部
0
希望看到您的想法,请您发表评论x