欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語言中database/sql的用法介紹

 更新時(shí)間:2023年05月19日 09:41:52   作者:今天撿到一百塊錢  
Go語言中的database/sql包定義了對數(shù)據(jù)庫的一系列操作,database/sql/driver包定義了應(yīng)被數(shù)據(jù)庫驅(qū)動(dòng)實(shí)現(xiàn)的接口,這些接口會(huì)被sql包使用,本文將詳細(xì)給大家介紹Go的database/sql的使用方法,需要的朋友可以參考下

零、windows系統(tǒng)安裝MySQL

mysqld --install // 將mysql設(shè)置成系統(tǒng)服務(wù)
mysqld --remove  // 取消MySQL作為系統(tǒng)服務(wù) 
  • 修改MySQL的登錄密碼
mysqladmin -uroot -p原密碼 password 新密碼
mysqladmin -uroot -p password 123456 // 剛安裝的MySQL默認(rèn)是沒有密碼的

一、簡介

Go 語言中的 database/sql 包定義了對數(shù)據(jù)庫的一系列操作。database/sql/driver 包定義了應(yīng)被數(shù)據(jù)庫驅(qū)動(dòng)實(shí)現(xiàn)的接口,這些接口會(huì)被 sql 包使用。但是 Go 語言沒有提供任何官方的數(shù)據(jù)庫驅(qū)動(dòng),所以我們需要導(dǎo)入第三方的數(shù)據(jù)庫驅(qū)動(dòng)。不過我們連接數(shù)據(jù)庫之后對數(shù)據(jù)庫操作的大部分代碼都使用sql 包。 目前go用的比較多的關(guān)系型數(shù)據(jù)庫有mysql和sqlite3,以下是第三方的驅(qū)動(dòng)地址。

二、連接數(shù)據(jù)庫

代碼實(shí)現(xiàn)

package main

import (
	"database/sql"
	_ "github.com/go-sql-driver/mysql" // It is important
	"log"
)

func main() {
	dsn := "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		panic(err)
	}

	// ping是嘗試連接MySQL數(shù)據(jù)庫
	if err = db.Ping(); err != nil {
		panic(err)
	}
	log.Println("連接成功")
    
    // 關(guān)閉連接
    defer db.Close()
}

代碼解釋

  • 使用mysql驅(qū)動(dòng),必須引入"github.com/go-sql-mysql/mysql"
  • dsn:是待連接數(shù)據(jù)庫信息。格式如下:
// username:password@[tcp(ip:port)]/dbname?charset=utf8mb4&parseTime=True&loc=Local
// 用戶名:密碼@[協(xié)議(地址:端口)]/數(shù)據(jù)庫名?charset=utf8mb4&parseTime=True&loc=Local

dsn := "root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
  • sql.Open():打開一個(gè)數(shù)據(jù)庫

  • Ping():檢驗(yàn)數(shù)據(jù)庫連接是否有效

三、增刪改查操作

1. 數(shù)據(jù)的增刪改查

package main

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

var db *sql.DB

// InitDB 數(shù)據(jù)庫連接初始化
func InitDB() (err error) {
	dsn := "root:1qa2ws3ed@tcp(127.0.0.1:3306)/gouse"

	db, err = sql.Open("mysql", dsn)
	CheckErr(err)

	err = db.Ping()
	CheckErr(err)
	fmt.Println("數(shù)據(jù)庫連接成功...")
	// 設(shè)置數(shù)據(jù)庫連接池最大連接數(shù)
	db.SetConnMaxLifetime(10)

	//設(shè)置最大閑置連接數(shù)
	db.SetMaxIdleConns(5)

	return

}

// CheckErr 統(tǒng)一處理錯(cuò)誤
func CheckErr(err error) {
	if err != nil {
		fmt.Println(err)
		panic(err)
	}
}

type User struct {
	ID       int32
	Username string
	Password string
	Email    string
}

func main() {
    if err := InitDB(); err != nil {
        fmt.Println("連接數(shù)據(jù)庫失敗")
        panic(err)
    }
    fmt.Println("接下來,請開始你的表演")
}

func createUser(user User) {
	// 1. 寫sql語句
	sqlStr := "insert into user (username. password, email) values(?, ?, ?)"

	// 2. 執(zhí)行sql語句
	exec, _ := db.Exec(sqlStr, user.Username, user.Password, user.Email)
	if affectCount, err := exec.RowsAffected(); affectCount == 0 && err != nil {
		fmt.Println("新建數(shù)據(jù)失敗")
		panic(err)
	}
	fmt.Println("新建數(shù)據(jù)成功")
}

func createUser(user User) {
	// 1. 寫sql語句
	sqlStr := "insert into user (username. password, email) values(?, ?, ?)"

	// 2. 執(zhí)行sql語句
	exec, _ := db.Exec(sqlStr, user.Username, user.Password, user.Email)
	if affectCount, err := exec.RowsAffected(); affectCount == 0 && err != nil {
		fmt.Println("新建數(shù)據(jù)失敗")
		panic(err)
	}
	fmt.Println("新建數(shù)據(jù)成功")
}

func createUser(user User) {
	// 1. 寫sql語句
	sqlStr := "insert into user (username. password, email) values(?, ?, ?)"

	// 2. 執(zhí)行sql語句
	exec, _ := db.Exec(sqlStr, user.Username, user.Password, user.Email)
	if affectCount, err := exec.RowsAffected(); affectCount == 0 && err != nil {
		fmt.Println("新建數(shù)據(jù)失敗")
		panic(err)
	}
	fmt.Println("新建數(shù)據(jù)成功")
}

func deleteUser(id int) {
	// 1. 寫sql語句
	sqlStr := "delete from user where id = ?"

	// 2. 執(zhí)行sql語句
	exec, _ := db.Exec(sqlStr, id)
	if affectCount, err := exec.RowsAffected(); affectCount == 0 && err != nil {
		fmt.Println("刪除數(shù)據(jù)失敗")
		panic(err)
	}
	fmt.Println("刪除數(shù)據(jù)成功")

}

func updateUser(user User) {
	// 1. 寫sql語句
	sqlStr := "update user set username = ?, password = ? where id = ?"

	// 2. 執(zhí)行sql語句
	exec, _ := db.Exec(sqlStr, user.Username, user.Password, user.ID)
	if affectCount, err := exec.RowsAffected(); affectCount == 0 && err != nil {
		fmt.Println("更新數(shù)據(jù)失敗")
		panic(err)
	}
	fmt.Println("更新數(shù)據(jù)成功")

}

func selectUserRow(id int32) {
	// 1. 寫sql語句
	sqlStr := "select * from user where id = ?"

	// 2. 執(zhí)行sql語句
	row := db.QueryRow(sqlStr, id)
	user := User{}
	err := row.Scan(&user.ID, &user.Username, &user.Password, &user.Email)
	if err != nil {
		fmt.Println("查詢數(shù)據(jù)失敗")
		panic(err)
	}
	fmt.Printf("id = %d,username = %s,password = %s,email = %s\n", user.ID, user.Username, user.Password, user.Email)
}

func selectUserRows(id []int) {
	// 1. 寫sql語句
	sqlStr := "select * from user where id in (?)"

	// 2. 執(zhí)行sql語句
	rows, err := db.Query(sqlStr, id)

	if err != nil {
		fmt.Println("查詢數(shù)據(jù)失敗")
		panic(err)
	}
	for rows.Next() {
		user := User{}
		err := rows.Scan(&user.ID, &user.Username, &user.Password, &user.Email)
		if err != nil {
			fmt.Println("解析數(shù)據(jù)失敗")
			panic(err)
		}
		fmt.Printf("id = %d,username = %s,password = %s,email = %s\n", user.ID, user.Username, user.Password, user.Email)
	}

}

2. SQL的預(yù)處理

  • 什么是預(yù)處理?
    • 普通SQL語句的執(zhí)行過程
      • 客戶端對SQL語句進(jìn)行占位符的替換得到了完整的SQL語句
      • 客戶端發(fā)送完整SQL語句到MySQL服務(wù)端
      • MySQL服務(wù)端執(zhí)行完整的SQL語句并將結(jié)果返回終端
    • 預(yù)處理的執(zhí)行過程
      • 先把SQL語句拆分成兩部分,SQL語句部分和參數(shù)部分
      • 先把SQL語句部分發(fā)送給MySQL服務(wù)端進(jìn)行SQL預(yù)處理
      • 然后參數(shù)部分發(fā)送給MySQL服務(wù)端,MySQL對SQL語句進(jìn)行拼接
      • MySQL服務(wù)端執(zhí)行完整的SQL語句返回結(jié)果
  • 為什么要預(yù)處理
    • 優(yōu)化MySQL服務(wù)器重復(fù)執(zhí)行SQL的方法。可以執(zhí)行服務(wù)器的性能,提前讓服務(wù)器編譯,一次編譯多次執(zhí)行,節(jié)省后續(xù)重復(fù)編譯的成本
    • 避免SQL注入

對于go中操作數(shù)據(jù)庫的預(yù)處理,方法是Proload,重要的是返回一個(gè)Stmt結(jié)構(gòu)體的指針,和之前的DB結(jié)構(gòu)體一樣的使用。

func preloadSelect(id int)  {
	// 1. 寫sql語句
	sqlStr := "select * from user where id = ?"

	stmt, err := db.Prepare(sqlStr)
	if err != nil {
		fmt.Println("預(yù)處理sql語句失敗")
		panic(err)
	}
	row := stmt.QueryRow(id)
	user := User{}
	err = row.Scan(&user.ID, &user.Username, &user.Password, &user.Email)
	if err != nil {
		fmt.Println("查詢數(shù)據(jù)失敗")
		panic(err)
	}
	fmt.Printf("id = %d,username = %s,password = %s,email = %s\n", user.ID, user.Username, user.Password, user.Email)
}

3. SQL的事務(wù)

在go中開啟數(shù)據(jù)庫的事務(wù)主要就是三個(gè)函數(shù):Begin()、Commit()、RollBack()

  • func (db *DB) Begin()(*Tx, error):開啟事務(wù)
  • func (tx *Tx) Commit() error:提交輸入
  • func (tx *Tx) Rollback() error:事務(wù)回滾、
func TranSaCtIon() {
	// 開啟事務(wù)
	tx, err := db.Begin()
    if err != nil {
        fmt.Println("開啟事務(wù)失敗")
        panic(err)
    }

	// 執(zhí)行多個(gè)SQL操作
	sqlStr := "update test set id=id+100000 where password = ?"
	result, err := tx.Exec(sqlStr, "xcxcxc")
	if err != nil {
        fmt.Println("更新數(shù)據(jù)事變")
        panic(err)
    }
	id, err := result.LastInsertId()
	if err != nil {
		// 語句回滾
		err := tx.Rollback()
		fmt.Println("事務(wù)回滾")
		if err != nil {
            fmt.Println("事務(wù)回滾失敗失敗")
            panic(err)
        }
	}
	fmt.Printf("修改后的id為%d\n", id)
}

以上就是Go語言中database/sql的用法介紹的詳細(xì)內(nèi)容,更多關(guān)于Go語言 database/sql的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Golang泛型的使用方法詳解

    Golang泛型的使用方法詳解

    這篇文章主要介紹了Golang中泛型的使用,Go和Python語言不同,處理不同數(shù)據(jù)類型非常嚴(yán)格。如Python可以定義函數(shù)帶兩個(gè)數(shù)值類型并返回較大的數(shù)值,但可以不嚴(yán)格指定參數(shù)類型為float或integer
    2022-12-12
  • Go使用協(xié)程交替打印字符

    Go使用協(xié)程交替打印字符

    這篇文章主要介紹了Go使用協(xié)程交替打印字符,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Go環(huán)境變量配置,及GOROOT、GOPATH的區(qū)別小結(jié)

    Go環(huán)境變量配置,及GOROOT、GOPATH的區(qū)別小結(jié)

    本文主要介紹了Go環(huán)境變量配置,及GOROOT、GOPATH的區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-09-09
  • golang壓縮與解壓縮文件的示例代碼

    golang壓縮與解壓縮文件的示例代碼

    這篇文章主要給大家介紹了golang壓縮與解壓縮文件,文中通過代碼示例給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-02-02
  • go xorm框架的使用

    go xorm框架的使用

    xorm框架和Spring Data Jpa有點(diǎn)相似,可以對比學(xué)習(xí),對于這個(gè)框架感覺還不錯(cuò),閑暇時(shí)間學(xué)習(xí)一下
    2021-05-05
  • Go語言框架快速集成限流中間件詳解

    Go語言框架快速集成限流中間件詳解

    這篇文章主要為大家介紹了Go語言框架快速集成限流中間件詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • 使用golang生成prometheus格式數(shù)據(jù)

    使用golang生成prometheus格式數(shù)據(jù)

    Prometheus是一個(gè)開源的監(jiān)控系統(tǒng),擁有許多Advanced?Feature,本文將介紹Primetheus?client的使用,并基于golang生成prometheus格式數(shù)據(jù),希望對大家有所幫助
    2025-02-02
  • 一文詳解golang中的gmp模型

    一文詳解golang中的gmp模型

    這篇文章主要介紹了golang中的gmp模型的誕生、概念及調(diào)度講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • golang 數(shù)組去重,利用map的實(shí)現(xiàn)

    golang 數(shù)組去重,利用map的實(shí)現(xiàn)

    這篇文章主要介紹了golang 數(shù)組去重,利用map的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Golang中time.After的使用理解與釋放問題

    Golang中time.After的使用理解與釋放問題

    這篇文章主要給大家介紹了關(guān)于Golang中time.After的使用理解與釋放問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08

最新評(píng)論