最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang操作MySql數(shù)據(jù)庫的完整步驟記錄

 更新時間:2020年11月16日 09:19:48   作者:路由器沒有路  
這篇文章主要給大家介紹了關于Golang操作MySql數(shù)據(jù)庫的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

MySQL是業(yè)界常用的關系型數(shù)據(jù)庫,在平時開發(fā)中會經(jīng)常與MySql數(shù)據(jù)庫打交道,所以在接下來將介紹怎么使用Go語言操作MySql數(shù)據(jù)庫。

下載MySql連接驅動

Go語言中的database/sql包提供了保證SQL或類SQL數(shù)據(jù)庫的泛用接口,并不提供具體的數(shù)據(jù)庫驅動。使用database/sql包時必須注入(至少)一個數(shù)據(jù)庫驅動。

我們常用的數(shù)據(jù)庫基本上都有完整的第三方實現(xiàn)。比如:MySQL驅動

**下載依賴**

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

**使用MySql驅動** 

func Open(driverName, dataSourceName string) (*DB, error)

Open打開一個dirverName指定的數(shù)據(jù)庫,dataSourceName指定數(shù)據(jù)源,一般至少包括數(shù)據(jù)庫文件名和其它連接必要的信息。

示例代碼:

import ( "database/sql"​ _ "github.com/go-sql-driver/mysql")​func main() { // DSN:Data Source Name dsn := "user:password@tcp(127.0.0.1:3306)/dbname" db, err := sql.Open("mysql", dsn) if err != nil { panic(err) } defer db.Close() // 注意這行代碼要寫在上面err判斷的下面}

初始化連接

Open函數(shù)可能只是驗證其參數(shù)格式是否正確,實際上并不創(chuàng)建與數(shù)據(jù)庫的連接。如果要檢查數(shù)據(jù)源的名稱是否真實有效,應該調用Ping方法。

返回的DB對象可以安全地被多個goroutine并發(fā)使用,并且維護其自己的空閑連接池。因此,Open函數(shù)應該僅被調用一次,很少需要關閉這個DB對象。

示例代碼如下:

// 定義一個全局對象dbvar db *sql.DB​// 定義一個初始化數(shù)據(jù)庫的函數(shù)func initDB() (err error) { // DSN:Data Source Name dsn := "user:password@tcp(127.0.0.1:3306)/sql_test?charset=utf8mb4&parseTime=True" // 不會校驗賬號密碼是否正確 // 注意?。?!這里不要使用:=,我們是給全局變量賦值,然后在main函數(shù)中使用全局變量db db, err = sql.Open("mysql", dsn) if err != nil { return err } // 嘗試與數(shù)據(jù)庫建立連接(校驗dsn是否正確) err = db.Ping() if err != nil { return err } return nil}​func main() { err := initDB() // 調用輸出化數(shù)據(jù)庫的函數(shù) if err != nil { fmt.Printf("init db failed,err:%v\n", err) return }}

其中sql.DB是表示連接的數(shù)據(jù)庫對象(結構體實例),它保存了連接數(shù)據(jù)庫相關的所有信息。它內部維護著一個具有零到多個底層連接的連接池,它可以安全地被多個goroutine同時使用。

**設置最大連接數(shù)**

func (db *DB) SetMaxOpenConns(n int)

SetMaxOpenConns設置與數(shù)據(jù)庫建立連接的最大數(shù)目。如果n大于0且小于最大閑置連接數(shù),會將最大閑置連接數(shù)減小到匹配最大開啟連接數(shù)的限制。如果n<=0,不會限制最大開啟連接數(shù),默認為0(無限制)。

**設置最大閑置連接數(shù)**

func (db *DB) SetMaxIdleConns(n int)

SetMaxIdleConns設置連接池中的最大閑置連接數(shù)。如果n大于最大開啟連接數(shù),則新的最大閑置連接數(shù)會減小到匹配最大開啟連接數(shù)的限制。如果n<=0,不會保留閑置連接。

MySql建庫建表

我們先在MySQL中創(chuàng)建一個名為`sql_test`的數(shù)據(jù)庫:

CREATE DATABASE sql_test;

進入該數(shù)據(jù)庫:

use sql_test;

執(zhí)行以下命令創(chuàng)建一張用于測試的數(shù)據(jù)表:

CREATE TABLE `user` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT, `name` VARCHAR(20) DEFAULT '', `age` INT(11) DEFAULT '0', PRIMARY KEY(`id`))ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

操作MySql查詢

為了方便查詢,我們事先定義好一個結構體來存儲user表的數(shù)據(jù)。

type user struct { id int age int name string}

**單行查詢**

單行查詢`db.QueryRow()`執(zhí)行一次查詢,并期望返回最多一行結果(即Row)。QueryRow總是返回非nil的值,直到返回值的Scan方法被調用時,才會返回被延遲的錯誤。(如:未找到結果)

func (db *DB) QueryRow(query string, args ...interface{}) *Row

示例代碼: 

// 查詢單條數(shù)據(jù)示例func queryRowDemo() { sqlStr := "select id, name, age from user where id=?" var u user // 非常重要:確保QueryRow之后調用Scan方法,否則持有的數(shù)據(jù)庫鏈接不會被釋放 err := db.QueryRow(sqlStr, 1).Scan(&u.id, &u.name, &u.age) if err != nil { fmt.Printf("scan failed, err:%v\n", err) return } fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age)}

**多行查詢**

多行查詢db.Query()執(zhí)行一次查詢,返回多行結果(即Rows),一般用于執(zhí)行select命令。參數(shù)args表示query中的占位參數(shù)。

func (db *DB) Query(query string, args ...interface{}) (*Rows, error)

示例代碼:

// 查詢多條數(shù)據(jù)示例func queryMultiRowDemo() { sqlStr := "select id, name, age from user where id > ?" rows, err := db.Query(sqlStr, 0) if err != nil { fmt.Printf("query failed, err:%v\n", err) return } // 非常重要:關閉rows釋放持有的數(shù)據(jù)庫鏈接 defer rows.Close()​ // 循環(huán)讀取結果集中的數(shù)據(jù) for rows.Next() { var u user err := rows.Scan(&u.id, &u.name, &u.age) if err != nil {  fmt.Printf("scan failed, err:%v\n", err)  return } fmt.Printf("id:%d name:%s age:%d\n", u.id, u.name, u.age) }}

操作MySql插入數(shù)據(jù)

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

func (db *DB) Exec(query string, args ...interface{}) (Result, error)

Exec執(zhí)行一次命令(包括查詢、刪除、更新、插入等),返回的Result是對已執(zhí)行的SQL命令的總結。參數(shù)args表示query中的占位參數(shù)。

具體插入數(shù)據(jù)示例代碼如下:

// 插入數(shù)據(jù)func insertRowDemo() { sqlStr := "insert into user(name, age) values (?,?)" ret, err := db.Exec(sqlStr, "王五", 38) if err != nil { fmt.Printf("insert failed, err:%v\n", err) return } theID, err := ret.LastInsertId() // 新插入數(shù)據(jù)的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)}

操作MySql更新數(shù)據(jù)

具體更新數(shù)據(jù)示例代碼如下:

// 更新數(shù)據(jù)func updateRowDemo() { sqlStr := "update user set age=? where id = ?" ret, err := db.Exec(sqlStr, 39, 3) if err != nil { fmt.Printf("update failed, err:%v\n", err) return } n, err := ret.RowsAffected() // 操作影響的行數(shù) if err != nil { fmt.Printf("get RowsAffected failed, err:%v\n", err) return } fmt.Printf("update success, affected rows:%d\n", n)}

操作MySql刪除數(shù)據(jù)

具體刪除數(shù)據(jù)的示例代碼如下:

// 刪除數(shù)據(jù)func deleteRowDemo() { sqlStr := "delete from user where id = ?" ret, err := db.Exec(sqlStr, 3) if err != nil { fmt.Printf("delete failed, err:%v\n", err) return } n, err := ret.RowsAffected() // 操作影響的行數(shù) if err != nil { fmt.Printf("get RowsAffected failed, err:%v\n", err) return } fmt.Printf("delete success, affected rows:%d\n", n)}

SQL注入安全問題

我們任何時候都不應該自己拼接SQL語句!

這里我們演示一個自行拼接SQL語句的示例,編寫一個根據(jù)name字段查詢user表的函數(shù)如下:

// sql注入示例func sqlInjectDemo(name string) { sqlStr := fmt.Sprintf("select id, name, age from user where name='%s'", name) fmt.Printf("SQL:%s\n", sqlStr) var u user err := db.QueryRow(sqlStr).Scan(&u.id, &u.name, &u.age) if err != nil { fmt.Printf("exec failed, err:%v\n", err) return } fmt.Printf("user:%#v\n", u)}

此時以下輸入字符串都可以引發(fā)SQL注入問題:

sqlInjectDemo("xxx' or 1=1#")sqlInjectDemo("xxx' union select * from user #")sqlInjectDemo("xxx' and (select count(*) from user) <10 #")

完整示例代碼歸檔GitHub

Golang操作MySql數(shù)據(jù)庫示例代碼

到此這篇關于Golang操作MySql數(shù)據(jù)庫的完整步驟記錄的文章就介紹到這了,更多相關Golang操作MySql數(shù)據(jù)庫內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • k8s容器互聯(lián)-flannel?host-gw原理篇

    k8s容器互聯(lián)-flannel?host-gw原理篇

    這篇文章主要為大家介紹了k8s容器互聯(lián)-flannel?host-gw原理篇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • Golang中crypto/cipher加密標準庫全面指南

    Golang中crypto/cipher加密標準庫全面指南

    本文主要介紹了Golang中crypto/cipher加密標準庫,包括對稱加密、非對稱加密以及使用流加密和塊加密算法,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2024-02-02
  • Goland?Gin?框架中的表單處理與數(shù)據(jù)綁定的操作方法

    Goland?Gin?框架中的表單處理與數(shù)據(jù)綁定的操作方法

    本文詳細介紹了Gin框架中表單處理的功能,包括數(shù)據(jù)綁定、驗證和文件上傳等,并通過一個完整的用戶注冊項目示例展示了實際應用,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • Golang開發(fā)之字符串與切片問題踩坑記錄

    Golang開發(fā)之字符串與切片問題踩坑記錄

    字符串和切片,都是golang常用的兩種內置數(shù)據(jù)類型,最近在日常工作中,遇到了一個字符串切片導致的問題,記錄一下排查問題的過程,避免后續(xù)在這種場景上踩坑
    2023-07-07
  • Go語言快速入門圖文教程

    Go語言快速入門圖文教程

    Go是 Goolge 開發(fā)的一種靜態(tài)型、編譯型、并發(fā)型,并具有垃圾回收功能的語言,Go 語言上手非常容易,它的風格類似于 C 語言,Go 語言號稱是互聯(lián)網(wǎng)時代的 C 語言,那么它到底有多火呢,一起看看吧
    2021-05-05
  • golang中gin框架接入jwt使用token驗證身份

    golang中gin框架接入jwt使用token驗證身份

    本文主要介紹了golang中gin框架接入jwt使用token驗證身份,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • golang連接mysql數(shù)據(jù)庫操作使用示例

    golang連接mysql數(shù)據(jù)庫操作使用示例

    這篇文章主要為大家介紹了golang連接mysql數(shù)據(jù)庫操作使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-04-04
  • 使用Go語言簡單模擬Python的生成器

    使用Go語言簡單模擬Python的生成器

    這篇文章主要介紹了使用Go語言簡單模擬Python的生成器,Python的generator是非??岬墓δ?用Go實現(xiàn)的代碼也較為簡潔,需要的朋友可以參考下
    2015-08-08
  • Golang unsafe.Sizeof函數(shù)代碼示例使用解析

    Golang unsafe.Sizeof函數(shù)代碼示例使用解析

    這篇文章主要為大家介紹了Golang unsafe.Sizeof函數(shù)代碼示例使用解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • Go語言實現(xiàn)類似c++中的多態(tài)功能實例

    Go語言實現(xiàn)類似c++中的多態(tài)功能實例

    Go本身不具有多態(tài)的特性,不能夠像Java、C++那樣編寫多態(tài)類、多態(tài)方法。但是,使用Go可以編寫具有多態(tài)功能的類綁定的方法。下面來一起看看吧
    2016-09-09

最新評論

高邮市| 台东市| 三门县| 娄底市| 雅江县| 合肥市| 临朐县| 靖西县| 新巴尔虎左旗| 凤凰县| 丰台区| 攀枝花市| 五峰| 阳曲县| 柳河县| 二连浩特市| 陇川县| 定襄县| 台南市| 景洪市| 前郭尔| 兴义市| 平江县| 雅江县| 肇庆市| 沛县| 乐亭县| 嘉义县| 武陟县| 新郑市| 蓬莱市| 禄劝| 江川县| 安吉县| 天台县| 郴州市| 五家渠市| 桃源县| 贵南县| 徐闻县| 双桥区|