• Go操作数据库之MySQL X


    安装mysql驱动:

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

    初始化模块

    go mod init m
    
    执行
    go mod tidy

    导入包:

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

    获得链接:

    package main
    
    import (
        "database/sql"
        _ "github.com/go-sql-driver/mysql"
        "time"
    )
    
    func main() {
        db, err := sql.Open("mysql", "root:123456@/go_db")
        if err != nil {
            panic(err)
        }
        print(db)
       // 最大连接时长
        db.SetConnMaxLifetime(time.Minute * 3)
       // 最大连接数
        db.SetMaxOpenConns(10)
        // 空闲连接数
        db.SetMaxIdleConns(10)
    }

    初始化连接

    Open函数可能只是验证其参数格式是否正确,实际上并不创建与数据库的连接。如果要检查数据源的名称是否真实有效,应该调用Ping方法。

    返回的DB对象可以安全地被多个goroutine并发使用,并且维护其自己的空闲连接池。因此,Open函数应该仅被调用一次,很少需要关闭这个DB对象。

    package main
    
    import (
        "database/sql"
        "fmt"
        _ "github.com/go-sql-driver/mysql"
    )
    
    // 定义一个全局对象db
    var db2 *sql.DB
    
    // 定义一个初始化数据库的函数
    func initDB() (err error) {
        dsn := "root:123456@tcp(127.0.0.1:3306)/go_db?charset=utf8mb4&parseTime=True"
        // 不会校验账号密码是否正确
        // 注意!!!这里不要使用:=,我们是给全局变量赋值,然后在main函数中使用全局变量db
        db2, err = sql.Open("mysql", dsn)
        if err != nil {
            return err
        }
        // 尝试与数据库建立连接(校验dsn是否正确)
        err = db2.Ping()
        if err != nil {
            return err
        }
        return nil
    }
    
    func main() {
        err := initDB() // 调用输出化数据库的函数
        if err != nil {
            fmt.Printf("初始化失败!,err:%v\n", err)
            return
        }else{
            fmt.Printf("初始化成功")
        }
    }

    当行查询:

    单行查询db.QueryRow()执行一次查询,并期望返回最多一行结果(即Row)。QueryRow总是返回非nil的值,直到返回值的Scan方法被调用时,才会返回被延迟的错误。

    定义结构体:

    type user struct {
        id int
        username string
        password string
    }
    // 查询一条用户数据
    func queryRowDemo() {
    sqlStr := "select id, username, password from user_tbl where id=?"
    var u user
    // 确保QueryRow之后调用Scan方法,否则持有的数据库链接不会被释放
    err := db.QueryRow(sqlStr, 1).Scan(&u.id, &u.username, &u.password)
    if err != nil {
    fmt.Printf("scan failed, err:%v\n", err)
    return
    }
    fmt.Printf("id:%d name:%s age:%s\n", u.id, u.username, u.password)
    }
    func main() {
    err := initDB() // 调用输出化数据库的函数
    if err != nil {
    fmt.Printf("初始化失败!,err:%v\n", err)
    return
    }else{
    fmt.Printf("初始化成功")
    }
    queryRowDemo()
    }

    查询多行

    多行查询db.Query()执行一次查询,返回多行结果(即Rows),一般用于执行select命令。参数args表示query中的占位参数。

    // 查询多条数据示例
    func queryMultiRow() {
    sqlStr := "select id, username, password from user_tbl where id > ?"
    rows, err := db.Query(sqlStr, 0)
    if err != nil {
    fmt.Printf("query failed, err:%v\n", err)
    return
    }
    // 非常重要:关闭rows释放持有的数据库链接
    defer rows.Close()
    
    // 循环读取结果集中的数据
    for rows.Next() {
    var u user
    err := rows.Scan(&u.id, &u.username, &u.password)
    if err != nil {
    fmt.Printf("scan failed, err:%v\n", err)
    return
    }
    fmt.Printf("id:%d username:%s password:%s\n", u.id, u.username, u.password)
    }
    }

    插入,更新和删除操作都使用Exec方法

    func (db *DB) Exec(query string, args ...interface{}) (Result, error)
    新增:
    // 插入数据
    func insertData() {
    sqlStr := "insert into user_tbl(username,password) values (?,?)"
    ret, err := db.Exec(sqlStr, "张三", "zs123")
    if err != nil {
    fmt.Printf("insert failed, err:%v\n", err)
    return
    }
    theID, err := ret.LastInsertId() // 新插入数据的id
    if err != nil {
    fmt.Printf("get lastinsert ID failed, err:%v\n", err)
    return
    }
    fmt.Printf("insert success, the id is %d.\n", theID)
    }
    
    
    删除:
    func delData() {
    sql := "delete from user_tbl where id =?"
    ret, err := db.Exec(sql, "1")
    if err != nil {
    fmt.Printf("删除失败, err:%v\n", err)
    return
    }
    rows, err := ret.RowsAffected()
    if err != nil {
    fmt.Printf("删除行失败, err:%v\n", err)
    return
    }
    fmt.Printf("删除成功, 删除的行数:%d.\n", rows)
    }
    
    
    更新:
    func updateData() {
    sql := "update user_tbl set username=?, password=? where id=?"
    ret, err := db.Exec(sql, "kite2", "kite123", "2")
    if err != nil {
    fmt.Printf("更新失败, err:%v\n", err)
    return
    }
    rows, err := ret.RowsAffected()
    if err != nil {
    fmt.Printf("更新行失败, err:%v\n", err)
    return
    }
    fmt.Printf("更新成功, 更新的行数:%d.\n", rows)
    }

    注意点:

    1.表名不能作为占位符使用

    "DELETE FROM `?` WHERE created_date BETWEEN ? AND ?" 
    
    ret, err := db3.Exec(sql, tableName, startDate, endDate)

    2.dsn中用户名和密码 如果包含特殊字符:!@#^*等,需要进行urlencode处理

    url.QueryEscape
  • 相关阅读:
    win10--安装python3.7.0和selenium
    mac下Jmeter的安装与环境变量配置
    Mac--PyCharm社区版配置git
    fiddler之简单的接口性能测试
    性能测试服务器瓶颈定位思路
    JMeter性能测试入门-不同类型线程组的使用
    jmeter连接数据库
    性能测试常见问题
    jmeter模拟spike尖峰测
    jmeter逻辑控制器详解(2)
  • 原文地址:https://www.cnblogs.com/xingxia/p/go_mysql.html
Copyright © 2020-2023  润新知