goweb-mysql鏈接

操做 數據庫

Go 語言中的 database/sql 包定義了對數據庫的一系列操做。database/sql/driver
包定義了應被數據庫驅動實現的接口,這些接口會被 sql 包使用。可是 Go 語言沒有提
供任何官方的數據庫驅動,因此咱們須要導入第三方的數據庫驅動。不過咱們鏈接數據
庫以後對數據庫操做的大部分代碼都使用 sql 包。mysql

獲取數據庫鏈接

Open 函數的說明

  • 參數 dataSourceName 的格式:
    數據庫用戶名:數據庫密碼@[tcp(localhost:3306)]/數據庫名
  • Open 函數可能只是驗證其參數,而不建立與數據庫的鏈接。若是要檢查數據
    源的名稱是否合法,應調用返回值的 Ping 方法。
  • 返回的 DB 能夠安全的被多個 go 程同時使用,並會維護自身的閒置鏈接池。
    這樣一來,Open 函數只需調用一次。不多須要關閉 DB
package utils

import (
    "database/sql"

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

var (
    Db  *sql.DB
    err error
)

func init() {
    Db, err = sql.Open("mysql", "root:ygj1007502524@tcp(localhost:3306)/test")
    if err != nil {
        panic(err.Error())
    }
}

增刪改操做

在鏈接的 test 數據庫中建立一個 users 表

CREATE TABLE users(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(100) UNIQUE NOT NULL,
PASSWORD VARCHAR(100) NOT NULL,
email VARCHAR(100)
)

向 users 表中插入記錄

package model

import (
    "fmt"
    "go_code/go-web/day01/web01_db/utils"
)

//User 結構體
type User struct {
    ID       int
    Username string
    Password string
    Email    string
}

//AddUser 添加User的方法一
func (user *User) AddUser() error {
    //1.寫sql語句
    sqlStr := "insert into users(username,password,email) values(?,?,?)"
    //2.預編譯
    inStmt, err := utils.Db.Prepare(sqlStr)
    if err != nil {
        fmt.Println("預編譯出現異常:", err)
        return err
    }
    //3.執行
    _, err2 := inStmt.Exec("admin", "123456", "admin@atguigu.com")
    if err2 != nil {
        fmt.Println("執行出現異常:", err2)
        return err
    }
    return nil
}

//AddUser2 添加User的方法二
func (user *User) AddUser2() error {
    //1.寫sql語句
    sqlStr := "insert into users(username,password,email) values(?,?,?)"
    //2.執行
    _, err := utils.Db.Exec(sqlStr, "admin2", "666666", "admin2@sina.com")
    if err != nil {
        fmt.Println("執行出現異常:", err)
        return err
    }
    return nil
}

單元測試

簡介

顧名思義,單元測試( unit test),就是一種爲驗證單元的正確性而設置的自動化測
試,一個單元就是程序中的一個模塊化部分。通常來講,一個單元一般會與程序中的一
個函數或者一個方法相對應,但這並非必須的。Go 的單元測試須要用到 testing 包
以及 go test 命令,並且對測試文件也有如下要求
1) 被測試的源文件和測試文件必須位於同一個包下
2) 測試文件必需要以_test.go 結尾git

  • 雖然 Go 對測試文件_test.go 的前綴沒有強制要求,不過通常咱們都設置
    爲被測試的文件的文件名,如:要對 user.go 進行測試,那麼測試文件的
    名字咱們一般設置爲 user_test.go
    3) 測試文件中的測試函數爲 TestXxx(t *testing.T)
  • 其中 Xxx 的首字母必須是大寫的英文字母
  • 函數參數必須是 test.T 的指針類型(若是是 Benchmark 測試則參數是
    testing.B 的指針類型)

測試代碼:

package model

import (
    "fmt"
    "testing"
)

//TestMain函數能夠在測試函數執行以前作一些其餘操做
func TestMain(m *testing.M) {
    fmt.Println("測試開始:")
    //經過m.Run()來執行測試函數
    m.Run()
}

func TestUser(t *testing.T) {
    fmt.Println("開始測試User中的相關方法")
    //經過t.Run()來執行子測試函數
    t.Run("測試添加用戶:", testAddUser)
}

//若是函數名不是以Test開頭,那麼該函數默認不執行,咱們能夠將它設置成爲一個子測試函數
func testAddUser(t *testing.T) {
    fmt.Println("子測試函數執行:")
    user := &User{}
    //調用添加用戶的方法
    user.AddUser()
    user.AddUser2()
}

testing 包的說明

若是一個測試函數的函數名的不是以 Test 開頭,那麼在使用 go test 命令時默
認不會執行,不過咱們能夠設置該函數時一個子測試函數,能夠在其餘測試函github

咱們還能夠經過 TestMain(m *testing.M)函數在測試以前和以後作一些其餘
的操做web

a) 測試文件中有 TestMain 函數時,執行 go test 命令將直接運行 TestMain
函數,不直接運行測試函數,只有在 TestMain 函數中執行 m.Run()時才
會執行測試函數sql

b) 若是想查看測試的詳細過程,可使用 go test -v 命令數據庫

獲取一條記錄

func (user *User) GetUserByID(userId int) (*User, error) {
//寫 sql 語句
sqlStr := "select id , username , password , email from users where id = ?"
//執行 sql
row := utils.Db.QueryRow(sqlStr, userId)
//聲明三個變量
var username string
var password string
var email string
//將各個字段中的值讀到以上三個變量中
err := row.Scan(&userId, &username, &password, &email)
if err != nil {
return nil, err
}
//將三個變量的值賦給 User 結構體
u := &User{
ID: userId,
Username: username,
Password: password,
Email: email,
}
return u, nil
}

獲取多條記錄

func (user *User) GetUsers() ([]*User, error) {
//寫 sql 語句
sqlStr := "select id , username , password , email from users"
//執行 sql
rows, err := utils.Db.Query(sqlStr)
if err != nil {
return nil, err
}
//定義一個 User 切片
var users []*User
//遍歷
for rows.Next() {
//聲明四個個變量
var userID int
var username string
var password string
var email string
//將各個字段中的值讀到以上三個變量中
err := rows.Scan(&userID, &username, &password, &email)
if err != nil {
return nil, err
}
//將三個變量的值賦給 User 結構體
u := &User{
ID: userID,
Username: username,
Password: password,
Email: email,
}
//將 u 添加到 users 切片中
users = append(users, u)
}
return users, nil
}
相關文章
相關標籤/搜索