golang连接MySQL数据库

安装配置mysql驱动

安装驱动

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

初始化模块

go mod init 模块名称

执行go mod tidy

go mod tidy

导入驱动

import (
    "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", "username:password@/dbname")
    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 (
    "fmt"
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
)

// 定义一个全局对象db
var db *sql.DB

// 定义一个初始化数据库的函数
func initDB() (err error) {
    
    
    dsn := "username:password@tcp(ip:port)/dbname?charset=utf8mb4&parseTime=True"
    // 不会校验账号密码是否正确
    db, err = sql.Open("mysql", dsn)
    if err != nil {
    
    
        return err
    }
    // 尝试与数据库建立连接(校验dsn是否正确)
    err = db.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方法被调用时,才会返回被延迟的错误。

// 查询一条用户数据
func queryOneRow() {
    
    
    sql := "SQL查询语句"
    var s struct{
    
    
    	attr1 type
    	attr2 type
    	...
    }{
    
    }
    // 确保QueryRow之后调用Scan方法,否则持有的数据库链接不会被释放
    err := db.QueryRow(sql, args1, args2...).Scan(&s.attr1, &s.attr2...)
    if err != nil {
    
    
        fmt.Printf("scan failed, err:%v\n", err)
        return
    }
    fmt.Printf("attr1:%v attr:%v...\n", s.attr1, s.attr2...)
}

例子:

u := struct {
    
    
    id int
    username string
    password string
}{
    
    }
sql := "select id, username, password from t_user where id=?"
err := db.QueryRow(sql, 1).Scan(&u.id, &u.username, &u.password)

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

// 查询多条数据示例
func queryMultiRow() {
    
    
    sql := "SQL查询语句"
    rows, err := db.Query(sql, args1, args2...)
    if err != nil {
    
    
        fmt.Printf("query failed, err:%v\n", err)
        return
    }
    // 非常重要:关闭rows释放持有的数据库链接
    defer rows.Close()

    // 循环读取结果集中的数据
    for rows.Next() {
    
    
	    var s struct{
    
    
	    	attr1 type
	    	attr2 type
	    	...
	    }{
    
    }
        err := rows.Scan(&s.attr1, &s.attr2...)
        if err != nil {
    
    
            fmt.Printf("scan failed, err:%v\n", err)
            return
        }
        fmt.Printf("attr1:%v attr:%v...\n", s.attr1, s.attr2...)
    }
}

例子:

sqlStr := "select id, username, password from user_tbl where id > ?"
rows, err := db.Query(sqlStr, 0)
defer rows.Close()
for rows.Next() {
    
    
    u := struct {
    
    
	    id int
	    username string
	    password string
	}{
    
    }
    err := rows.Scan(&u.id, &u.username, &u.password)
}

插入、更新、删除数据

插入、更新、删除操作都使用Exec方法。

func (db *DB) Exec(query string, args ...interface{
    
    }) (Result, error)
// 插入、更新、删除数据
func operateData() {
    
    
    sql := "SQL插入、更新和删除语句"
    ret, err := db.Exec(sql, args1, args2...)
    if err != nil {
    
    
        fmt.Printf("operate failed, err:%v\n", err)
        return
    }
    rows, err := ret.RowsAffected() //操作影响的行数
	//theID, err := ret.LastInsertId() // 新插入数据的id
    if err != nil {
    
    
        fmt.Printf("operate failed, err:%v\n", err)
        return
    }
    fmt.Printf("operate success, the number of rows is %d.\n", rows)
}

猜你喜欢

转载自blog.csdn.net/ymxyld/article/details/124916816
今日推荐