go 返回mysql數組_Go基礎之--操作Mysql(一)

關于標準庫database/sql

database/sql是golang的標準庫之一,它提供了一系列接口方法,用于訪問關系數據庫。它并不會提供數據庫特有的方法,那些特有的方法交給數據庫驅動去實現。

database/sql庫提供了一些type。這些類型對掌握它的用法非常重要。

DB

數據庫對象。 sql.DB類型代表了數據庫。和其他語言不一樣,它并是數據庫連接。golang中的連接來自內部實現的連接池,連接的建立是惰性的,當你需要連接的時候,連接池會自動幫你創建。通常你不需要操作連接池。一切都有go來幫你完成。

Results

結果集。數據庫查詢的時候,都會有結果集。sql.Rows類型表示查詢返回多行數據的結果集。sql.Row則表示單行查詢結果的結果集。當然,對于插入更新和刪除,返回的結果集類型為sql.Result。

Statements

語句。sql.Stmt類型表示sql查詢語句,例如DDL,DML等類似的sql語句。可以把當成prepare語句構造查詢,也可以直接使用sql.DB的函數對其操作。

而通常工作中我們可能更多的是用https://github.com/jmoiron/sqlx包來操作數據庫

sqlx是基于標準庫database/sql的擴展,并且我們可以通過sqlx操作各種類型的數據如

和其他語言不通的是,查詢數據庫的時候需要創建一個連接,對于go而言則是需要創建一個數據庫對象,連接將會在查詢需要的時候,由連接池創建并維護,使用sql.Open函數創建數據庫對象,第一個參數是數據庫驅動名,第二個參數是一個連接字符串

關于數據庫的增刪查改

增加數據

關于增加數據幾個小知識點:

關于插入數據的時候占位符是通過問號:?

插入數據的后可以通過LastInsertId可以獲取插入數據的id

通過RowsAffected可以獲取受影響的行數

執行sql語句是通過exec

一個簡單的使用例子:

package main

import ("github.com/jmoiron/sqlx"_"github.com/go-sql-driver/mysql"

"fmt")

func main() {

Db,err:=sqlx.Open("mysql","root:123456@tcp(192.168.14.7:3306)/godb")if err !=nil{

fmt.Println("connect to mysql failed,",err)

return

}

defer Db.Close()

fmt.Println("connect to mysql success")//執行sql語句,切記這里的占位符是?

result,err := Db.Exec("INSERT INTO user_info(username,sex,email)VALUES (?,?,?)","user01","男","8989@qq.com")if err !=nil{

fmt.Println("insert failed,",err)

}//通過LastInsertId可以獲取插入數據的id

userId,err:=result.LastInsertId()//通過RowsAffected可以獲取受影響的行數

rowCount,err:=result.RowsAffected()

fmt.Println("user_id:",userId)

fmt.Println("rowCount:",rowCount)

}

通過Exec方法插入數據,返回的結果是一個sql.Result類型

查詢數據

下面是一個查詢的例子代碼:

//執行查詢操作

rows,err := Db.Query("SELECT email FROM user_info WHERE user_id>=5")if err !=nil{

fmt.Println("select db failed,err:",err)

return

}// 這里獲取的rows是從數據庫查的滿足user_id>=5的所有行的email信息,rows.Next(),用于循環獲取所有

for rows.Next(){

var s string

err= rows.Scan(&s)if err !=nil{

fmt.Println(err)

return

}

fmt.Println(s)

}

rows.Close()

使用了Query方法執行select查詢語句,返回的是一個sql.Rows類型的結果集

迭代后者的Next方法,然后使用Scan方法給變量s賦值,以便取出結果。最后再把結果集關閉(釋放連接)。

同樣的我們還可以通過Exec方式執行查詢語句

但是因為Exec返回的是一個sql.Result類型,從官網這里:

https://golang.google.cn/pkg/database/sql/#typeResult

我們可以直接這個接口里只有兩個方法:LastInsertId(),RowsAffected()

我們還可以通過Db.Get()方法獲取查詢的數據,將查詢的數據保存到一個結構體中

//Get執行查詢操作

type user_info struct {

Username string `db:"username"`

Email string `db:"email"`

}

var userInfo user_info

err= Db.Get(&userInfo,"SELECT username,email FROM user_info WHERE user_id=5")if err !=nil{

fmt.Println(err)

return

}

fmt.Println(userInfo)

這樣獲取的一個數據,如果我們需要獲取多行數據信息還可以通過Db.Select方法獲取數據,代碼例子為:

var userList []*user_info

err= Db.Select(&userList,"SELECT username,email FROM user_info WHERE user_id>5")if err !=nil{

fmt.Println(err)

return

}

fmt.Println(userList)

for _,v:=range userList{

fmt.Println(v)

}

通過Db.Select方法將查詢的多行數據保存在一個切片中,然后就可以通過循環的方式獲取每行數據

更新數據

下面是一個更新的例子,這里是通過Exec的方式執行的

//更新數據

results,err := Db.Exec("UPDATE user_info SET username=? where user_id=?","golang",5)if err !=nil{

fmt.Println("update data fail,err:",err)

return

}

fmt.Println(results.RowsAffected())

刪除數據

下面是一個刪除的例子,同樣是通過Exec的方式執行的

//刪除數據

results,err := Db.Exec("DELETE from user_info where user_id=?",5)if err !=nil{

fmt.Println("delete data fail,err:",err)

return

}

fmt.Println(results.RowsAffected())

通過上面的簡單例子,對golang操作mysql的增刪查改,有了一個基本的了解,下面整理一下重點內容

sql.DB

當我們調用sqlx.Open()可以獲取一個sql.DB對象,sql.DB是數據庫的抽象,切記它不是數據庫連接,sqlx.Open()只是驗證數據庫參數,并沒不創建數據庫連接。sql.DB提供了和數據庫交互的函數,同時也管理維護一個數據庫連接池,并且對于多gegoroutines也是安全的

sql.DB表示是數據庫抽象,因此你有幾個數據庫就需要為每一個數據庫創建一個sql.DB對象。因為它維護了一個連接池,因此不需要頻繁的創建和銷毀。

連接池

只用sql.Open函數創建連接池,可是此時只是初始化了連接池,并沒有創建任何連接。連接創建都是惰性的,只有當真正使用到連接的時候,連接池才會創建連接。連接池很重要,它直接影響著你的程序行為。

連接池的工作原來卻相當簡單。當你的函數(例如Exec,Query)調用需要訪問底層數據庫的時候,函數首先會向連接池請求一個連接。如果連接池有空閑的連接,則返回給函數。否則連接池將會創建一個新的連接給函數。一旦連接給了函數,連接則歸屬于函數。函數執行完畢后,要不把連接所屬權歸還給連接池,要么傳遞給下一個需要連接的(Rows)對象,最后使用完連接的對象也會把連接釋放回到連接池。

請求連接的函數有幾個,執行完畢處理連接的方式也不同:

db.Ping() 調用完畢后會馬上把連接返回給連接池。

db.Exec() 調用完畢后會馬上把連接返回給連接池,但是它返回的Result對象還保留這連接的引用,當后面的代碼需要處理結果集的時候連接將會被重用。

db.Query() 調用完畢后會將連接傳遞給sql.Rows類型,當然后者迭代完畢或者顯示的調用.Clonse()方法后,連接將會被釋放回到連接池。

db.QueryRow()調用完畢后會將連接傳遞給sql.Row類型,當.Scan()方法調用之后把連接釋放回到連接池。

db.Begin() 調用完畢后將連接傳遞給sql.Tx類型對象,當.Commit()或.Rollback()方法調用后釋放連接。

每個連接都是惰性的,如何驗證sql.Open調用之后,sql.DB對象可用,通過db.Ping()初始化

代碼例子:

package main

import ("github.com/jmoiron/sqlx"_"github.com/go-sql-driver/mysql"

"fmt")

func main() {

Db, err := sqlx.Open("mysql", "root:123456@tcp(192.168.50.166:3306)/godb")if err !=nil {

fmt.Println("connect to mysql failed,", err)

return

}

defer Db.Close()

fmt.Println("connect to mysql success")

err=Db.Ping()if err !=nil{

fmt.Println(err)

return

}

fmt.Println("ping success")

}

需要知道:當調用了ping之后,連接池一定會初始化一個數據連接

連接失敗

database/sql 其實幫我們做了很多事情,我們不用見擦汗連接失敗的情況,當我們進行數據庫操作的時候,如果連接失敗,database/sql 會幫我們處理,它會自動連接2次,這個如果查看源碼中我們可以看到如下的代碼:

// ExecContext executes a querywithout returning any rows.// The args are for any placeholder parameters in the query.

func (db*DB) ExecContext(ctx context.Context, querystring, args ...interface{}) (Result, error) {

var res Result

var err error

for i := 0; i < maxBadConnRetries; i++{

res, err= db.exec(ctx, query, args, cachedOrNewConn)if err !=driver.ErrBadConn {

break

}

}if err ==driver.ErrBadConn {

return db.exec(ctx,query, args, alwaysNewConn)

}

return res, err

}

上述代碼中變量maxBadConnRetries小時如果連接失敗嘗試的次數,默認是2

關于連接池配置

db.SetMaxIdleConns(n int) 設置連接池中的保持連接的最大連接數。默認也是0,表示連接池不會保持釋放會連接池中的連接的連接狀態:即當連接釋放回到連接池的時候,連接將會被關閉。這會導致連接再連接池中頻繁的關閉和創建。

db.SetMaxOpenConns(n int) 設置打開數據庫的最大連接數。包含正在使用的連接和連接池的連接。如果你的函數調用需要申請一個連接,并且連接池已經沒有了連接或者連接數達到了最大連接數。此時的函數調用將會被block,直到有可用的連接才會返回。設置這個值可以避免并發太高導致連接mysql出現too many connections的錯誤。該函數的默認設置是0,表示無限制。

db.SetConnMaxLifetime(d time.Duration) 設置連接可以被使用的最長有效時間,如果過期,連接將被拒絕

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/281768.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/281768.shtml
英文地址,請注明出處:http://en.pswp.cn/news/281768.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vue CLI 3開發中屏蔽煩人的EsLint錯誤

問題 Vue開發中&#xff0c;特別是當你閱讀分析別人的其中早期版本的Vue代碼時往往會遭遇到滿屏幕的煩人的EsLint錯誤。有關EsLint這個工具的作用不再贅述。查閱網上參考文檔&#xff0c;大多是針對早起版本Vue CLI工具項目的&#xff0c;在我最新使用的Vue CLI 3生成的工程中根…

pyinstaller---將py文件打包成exe

pyinstaller可將Python腳本打包成可執行程序&#xff0c;使在沒有Python環境的機器上運行。 1.pyinstaller在windows下的安裝 直接在命令行用pip安裝 pyinstaller&#xff0c; 在windows下&#xff0c;pyinstaller需要PyWin32的支持。當用pip安裝pyinstaller時未找到PyWin32&am…

老人尋求到一名程序員,用2W行代碼給自己打造了一幅肖像畫

今天翻墻看了下國外的論壇&#xff0c;看到了一位版主給一位老人描繪肖像畫的文章&#xff0c;不得不說這位大佬是真的厲害&#xff0c;近20000行代碼&#xff0c;而且還畫的很像&#xff0c;像小編我這種手殘黨&#xff0c;用筆也不能畫出來&#xff0c;不得不服&#xff0c;今…

一題多解,ASP.NET Core應用啟動初始化的N種方案[下篇]

[接上篇]“天下大勢&#xff0c;分久必合&#xff0c;合久必分”&#xff0c;ASP.NET應用通過GenericWebHostService這個承載服務被整合到基于IHostBuilder/IHost的服務承載系統中之后&#xff0c;也許微軟還是意識到Web應用和后臺服務的承載方式還是應該加以區分&#xff0c;于…

java jpa 模糊查詢_JPA 以SQL實現分頁不模糊查詢(參數可能為空)

repository代碼:package com.fancy.miniflow.repository;import java.util.List;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.data.jpa.repository.JpaSpecificationExecutor;import org.springframework.data.jpa.repository.Q…

GitHub服務中斷24小時11分鐘事故分析報告\n

上周&#xff0c;GitHub經歷了一次事故&#xff0c;導致服務降級24小時11分鐘。雖然平臺的某些部分不受事故影響&#xff0c;但仍然有多個內部系統受到了影響&#xff0c;向用戶顯示了過時且不一致的內容。所幸沒有用戶數據丟失&#xff0c;但針對幾秒鐘數據庫寫入的手動調整工…

8 旋轉數組的最小數字

輸入一個遞增排序數組的一個旋轉&#xff0c;輸出旋轉數組的最小元素例如1,2,3,4,5的一個旋轉可以為3,4,5,1,2把一個數組的最開始若干個元素搬到數組的末尾&#xff0c;稱之為數組的旋轉 輸出旋轉數組的最小元素 C: 1 class Solution {2 public:3 int minInOrder(vector<…

軟考新思維--2017年上半年信息系統項目管理師上午試題分析與答案(試題6-10題)...

2017年上半年信息系統項目管理師上午試題分析與答案&#xff08;試題1-5題&#xff09; 6.&#xff08;&#xff09;不是獲取需求的方法。A、問卷調查B、會議討論C、獲取原型D、決策分析【軟考新思維】需求是獲取的得來的&#xff0c;不是決策得來的。 先是獲取需求&#xff0c…

php 合并 字符串_PHP如何去重合并字符串

本篇文章主要給大家介紹PHP如何去重合并字符串。推薦教程&#xff1a;《PHP教程》對于PHP學習者來說&#xff0c;合并多個字符串&#xff0c;應該并不是很難。但是如果這多個字符串中&#xff0c;有相同元素&#xff0c;當我們想要合并他們并且要使其值具有唯一值。也就是說合并…

10.31T4 HAOI2010最長公共子序列 計數+容斥原理

2775 -- 【HAOI2010】最長公共子序列 Description 字符序列的子序列是指從給定字符序列中隨意地&#xff08;不一定連續&#xff09;去掉若干個字符&#xff08;可能一個也不去掉&#xff09;后所形成的字符序列。令給定的字符序列X“x0&#xff0c;x1&#xff0c;…&#xff0…

軟概(lesson 2):課堂測試

一、測試題目 二、完成過程 1.設計思想 ①連接mysql數據庫 ②設計user類&#xff0c;增加參數 ③設計add類&#xff0c;向數據庫內增加內容 ④設計addInput頁面&#xff0c;完成錄入操作 ⑤設計add頁面&#xff0c;接收錄入的參數&#xff0c;并調用add類函數 2.源代碼 user.ja…

谷歌Gboard輸入法新增“無痕模式”:僅在Chrome隱身窗口中適用

據外媒Android Police報道&#xff0c;如大家所知道的&#xff0c;Chrome瀏覽器中的“隱身模式”是為了防止你的私密瀏覽記錄被其他人看到&#xff0c;但是&#xff0c;在這種模式下&#xff0c;你的輸入法鍵盤依然會記住你輸入的短語&#xff0c;為了阻止你的鍵盤在Chrome隱身…

php兩個數組融合,php合并兩個數組的方式有哪些

1、arrary_merge示例代碼&#xff1a;$arr1 array(1, 2, 3, 4, 5);$arr2 array(1, 2, 6, 7, 8, 9, 10);$result1 array_merge($arr1, $arr2);$arr3 array("name" > "itbsl", "age" > 13, "sex" > "Male");$arr…

最近對latin-1這個字符集產生了不少好感

【簡介】 最近我要解析一個數據庫中間件的日志、這個中間件會在日志中記錄SQL發往的后臺DB ,執行耗時&#xff0c;對應的SQL&#xff1b;中間件直接把SQL寫到 了日志中去&#xff0c;并沒有對SQL進行適當的編碼轉換&#xff1b;理想情況下這個也不會有什么問題&#xff0c;不幸…

面象對象設計原則之六:迪米特原則(LeastKnowledge Principle, LKP)

迪米特法則來自于1987年美國東北大學(Northeastern University)一個名為“Demeter”的研究項目。迪米特法則又稱為最少知識原則(LeastKnowledge Principle, LKP)&#xff0c;其定義如下&#xff1a; 迪米特法則(Law of Demeter, LoD)&#xff1a;一個軟件實體應當盡可能少地與…

php symfony urlmatcher-gt;match,symfony路由組件(The Routing Component)

The Routing component 把HTTP request轉換為一系列的配置參數.安裝你有兩種方式來安裝這個組件:通過 Composer (symfony/routing on Packagist);使用官方的 Git repository (https://github.com/symfony/Routing)。然后, 需要Composer把vendor/autoload.php 這個文件提供 給 a…

R升級和包更新

1.R升級 # 安裝包"installr" install.packages("installr") # 導入包 library(installr) # 升級 updateR() 2.包升級 # 包升級 update.packages() 3.安裝包 # 選擇鏡像 options(reposstructure(c(CRAN"https://cran.cnr.berkeley.edu/"))) # 安裝…

其他對象的表單

1.textarea&#xff1a; textarea對象就想是input對象中的text樣式的表單&#xff0c;只不過是擴展過的text樣式表單。它可以通過行&#xff08;rows&#xff09;屬性和列&#xff08;cols&#xff09;屬性來編輯文本域的大小。最常見于留言板、論壇時回帖時的文本框等。 <h…

WinForm(十三)WebView2

WebView是WinForm框架中一個控件&#xff0c;用來對網頁信息交互&#xff0c;有時Web自己開發的&#xff0c;有時Web是三方的。下面通過一個例子來看看WebView2的使用。首先看Web的邏輯&#xff0c;是一個商品添加頁面&#xff0c;用AlpineJS和BootStrap來開發的&#xff0c;業…

Fluent UDF【4】:C語言

Fluent UDF利用的是C語言&#xff0c;本文簡單介紹在UDF中經常會用到的C語言常識。 本文部分內容來自UDF手冊。 1 C語言中的注釋 C語言中的注釋利用/*及*/來實現。例如: /*這是一個注釋*/ 注釋也可以跨行實現&#xff0c;如: /*這是一個 跨行注釋*/ 注意:在編寫UDF的過程中&…