1. 程式人生 > >Redis資料庫學習筆記03--go語言與Redis資料庫簡單互動

Redis資料庫學習筆記03--go語言與Redis資料庫簡單互動

目錄

1.使用go語言與redis資料庫互動配置

1.1 安裝redis資料庫操作工具包redigo

1.2 測試redigo工具包是否正常工作

1.3 redigo工具包來源

1.4 go get命令概述

2.redigo工具包簡單使用說明

3.go語言與Redis資料庫簡單互動

3.1 準備工作

3.2 連結redis資料庫

3.3 使用send方法對redis資料庫寫入資料

3.4 使用do方法對redis資料庫讀寫資料

3.5 使用Scan介面和Values介面操作多條不同型別資料

3.6 通過序列化與反序列化方法對redis資料庫進行復雜資料的讀寫操作


1.使用go語言與redis資料庫互動配置

由於NoSQL型別的資料庫並沒有統一的執行標準,因此對於redis資料庫來說想要操作就必須先找到一套趁手的工具,或者自己建立一套。當然我這初學者只能先使用別人的工具了,稍後再說工具的出處,我們直奔主題先將工具安裝完畢保證能夠使用go來操作redis之後再聊別的。

1.1 安裝redis資料庫操作工具包redigo

直接執行指令:【~/ $ go get -u -v github.com/gomodule/redigo/redis】,在網路正常的情況下會在幾秒鐘之內下載並安裝完畢。

***deMacBook-Pro:~ ***$ go get -u -v github.com/gomodule/redigo/redis
github.com/gomodule/redigo (download)
github.com/gomodule/redigo/redis

***deMacBook-Pro:~ ***$

1.2 測試redigo工具包是否正常工作

測試redigo工具包是否正常工作,實際上就是測試go語言能否通過redigo提供的方法來對redis資料庫進行編輯或新增內容。所以我們需要先在go的環境下建立一個.go測試檔案,至於名字無所謂就叫test.go就行。

***deMacBook-Pro:~ ***$ ls
Desktop Downloads Movies Pictures
Documents Library Music Public

***deMacBook-Pro:~ ***$ cd Desktop/
***deMacBook-Pro:Desktop ***$ ls
goLearn goTest                   #我自己桌面上就倆資料夾,一個goLearn是beego寫程式碼的workSpace,一個goTest是git路徑。

***deMacBook-Pro:Desktop ***$ cd goTest
***deMacBook-Pro:goTest ***$ ls
README.md conf models static views
a.code controllers project02 temp.code
b.code main.go routers tests

shangyujiedeMacBook-Pro:goTest shangyujie$ vim test.go

然後在test.go測試檔案中新增下列go程式碼內容,直接:wq儲存退出。這段程式碼的含義是能夠向redis資料庫中新增一條key為c1,value為hello的資料。

package main
import ( "github.com/gomodule/redigo/redis")

func main(){
    conn,_ := redis.Dial("tcp", ":6379")
    defer conn.Close()
    conn.Do("set", "c1", "hello")
}

然後將這個test.go檔案編譯,然後執行它。

***deMacBook-Pro:goTest ***$ ls
README.md conf models static tests
a.code controllers project02 temp.code views
b.code main.go routers test.go        #test.go是剛剛建立的

***MacBook-Pro:goTest ***$ go build test.go
***deMacBook-Pro:goTest ***$ ls
README.md conf models static test.go
a.code controllers project02 temp.code tests
b.code main.go routers test views     #go build編譯檔案會生成一個test檔案
            
***deMacBook-Pro:goTest ***$ ./test   #執行這個test檔案
                

然後進入redis資料庫,如果能夠檢視到非手動新增的key的value值證明環境配置成功。

***deMacBook-Pro:goTest ***$ redis-cli
127.0.0.1:6379> get c1
"hello"

127.0.0.1:6379>

OK 搞定!配置完成。

1.3 redigo工具包來源

由於redis是一個NoSQL資料庫,因此並不存在所謂的統一標準操作語言。所以在官網redis.cn中選擇客戶端來選擇我們對應的語言。

然後在下面支援的語言中選擇go語言

然後下面有很多可以提供go-redis相互操作的工具包,我選的是星標的redigo工具。點選branch標誌分支標誌準備去github下載工具包

進入github頁面資源分享頁面,能夠看到readMe中說明維護地址已經發生轉移,所以複製連結github.com/gomodule/redigo繼續跳轉

在跳轉到的頁面中發現有redis資料夾,終於發現redigo本體。所以最終工具包下載路徑就是github.com/gomodule/redigo/redis。

1.4 go get命令概述

go get命令可以根據要求和實際情況,從網際網路上下載或更新指定的程式碼包及其依賴包並對它們進行編譯和安裝。其中-u 和-v是比較常見的兩個命令標記。

標記名稱

標記描述

-d

讓命令程式只執行下載動作,而不執行安裝動作。

-f

僅在使用-u標記時才有效。該標記會讓命令程式忽略掉對已下載程式碼包的匯入路徑的檢查。如果下載並安裝的程式碼包所屬的專案是你從別人那裡Fork過來的,那麼這樣做就尤為重要了。

-fix

讓命令程式在下載程式碼包後先執行修正動作,而後再進行編譯和安裝。

-insecure

允許命令程式使用非安全的scheme(如HTTP)去下載指定的程式碼包。如果你用的程式碼倉庫(如公司內部的Gitlab)沒有HTTPS支援,可以新增此標記。請在確定安全的情況下使用它。

-t

讓命令程式同時下載並安裝指定的程式碼包中的測試原始碼檔案中依賴的程式碼包。

-u

讓命令利用網路來更新已有程式碼包及其依賴包。預設情況下,該命令只會從網路上下載本地不存在的程式碼包,而不會更新已有的程式碼包。

-v

打印出被構建的程式碼包的名字

-x

打印出用到的命令

所以剛剛下載redigo工具包的指令就是【~/ $ go get -u -v github.com/gomodule/redigo/redis】,表示使用go get -u 指令去github指定url處下載redis工具包並安裝,並採用-v標記將安裝過程展示。

2.redigo工具包簡單使用說明

redigo工具包使用說明文件地址:https://godoc.org/github.com/gomodule/redigo/redis,內部有redigo工具包所有具體的詳細說明。一般情況下redigo主要使用的只有三大類介面:

  • 連線指令介面:以Dial開頭的介面全都是,但是一般只使用Dial介面足夠用。
  • 執行指令介面:Do 和 Send 主要就這兩個指令介面
  • 轉換指令介面:Index下的Variables類介面

三種介面主要特殊說明一下轉換指令介面。這一類介面在文件頁面檢索Index,得到的結果都是轉換指令介面。他們存在的目的在於:因為redis中所有的value都必須是string型別,所以當儲存其他資料型別的時候需要進行資料型別轉換,而當資料被從redis中取出後也要進行資料型別轉換從而變回原來的資料型別。轉換型別介面就是用來做資料型別轉換工作的。

需要了解一點就是redis資料庫近年來逐漸在升溫,使用的頻度也越來越高。但是這並不意味著redis資料庫就什麼都好,可以徹底摒棄mysql這類關係型資料庫轉而完全投入redis的懷抱,畢竟兩種資料庫結構決定了他們的優勢方向不同。關係型資料庫適用於儲存大量的、不會頻繁讀寫的資料,而記憶體型資料庫則適用於儲存一些經常使用、載入非常頻繁的資料。這具體可以參考https://blog.csdn.net/qq_26050385/article/details/80983508博主文章。所以兩者綜合使用是一個比較好的也是現在的一個趨勢的選擇。例如資料原本存放在mysql中,可以在第一次載入的時候將資料存入redis中,而後如果需要再次獲取資料就從redis裡面獲取。這樣就能大大提高頁面的載入速度。

3.go語言與Redis資料庫簡單互動

3.1 準備工作

第一步:準備redis乾淨資料庫

***deMacBook-Pro:~ ***$ redis-cli
127.0.0.1:6379> keys *
(empty list or set)

第二步:使用beego建立乾淨的go工程

***deMacBook-Pro:~ ***$ bee new goredistest
______
| ___ \
| |_/ /  ___   ___
| ___ \ / _ \ / _ \
| |_/ /|  __/|  __/
\____/  \___| \___| v1.10.0
2018/12/12 23:42:51 WARN     ▶ 0001 You current workdir is not inside $GOPATH/src.
2018/12/12 23:42:51 INFO     ▶ 0002 Creating application...
	create	 /Users/***/Desktop/goLearn/src/goredistest/
	create	 /Users/***/Desktop/goLearn/src/goredistest/conf/
	create	 /Users/***/Desktop/goLearn/src/goredistest/controllers/
	create	 /Users/***/Desktop/goLearn/src/goredistest/models/
	create	 /Users/***/Desktop/goLearn/src/goredistest/routers/
	create	 /Users/***/Desktop/goLearn/src/goredistest/tests/
	create	 /Users/***/Desktop/goLearn/src/goredistest/static/
	create	 /Users/***/Desktop/goLearn/src/goredistest/static/js/
	create	 /Users/***/Desktop/goLearn/src/goredistest/static/css/
	create	 /Users/***/Desktop/goLearn/src/goredistest/static/img/
	create	 /Users/***/Desktop/goLearn/src/goredistest/views/
	create	 /Users/***/Desktop/goLearn/src/goredistest/conf/app.conf
	create	 /Users/***/Desktop/goLearn/src/goredistest/controllers/default.go
	create	 /Users/***/Desktop/goLearn/src/goredistest/views/index.tpl
	create	 /Users/***/Desktop/goLearn/src/goredistest/routers/router.go
	create	 /Users/***/Desktop/goLearn/src/goredistest/tests/default_test.go
	create	 /Users/***/Desktop/goLearn/src/goredistest/main.go
2018/12/12 23:42:51 SUCCESS  ▶ 0003 New application successfully created!
***deMacBook-Pro:~ ***$ 

第三步:使用IDE開啟,找到controllers/default.go,準備編寫測試程式碼

準備完畢。

3.2 連結redis資料庫

3.3 使用send方法對redis資料庫寫入資料

圖中使用redigo工具介面send向redis資料庫中寫入了兩個欄位,分別是frankName和frankAge。

在終端命令中使用beego指令開啟伺服器

***deMacBook-Pro:goRedis ***$ bee run
______
| ___ \
| |_/ /  ___   ___
| ___ \ / _ \ / _ \
| |_/ /|  __/|  __/
\____/  \___| \___| v1.10.0
2018/12/12 12:57:12 INFO     ▶ 0001 Using 'goRedis' as 'appname'
2018/12/12 12:57:12 INFO     ▶ 0002 Initializing watcher...
goRedis/controllers
goRedis/routers
goRedis
2018/12/12 12:57:18 SUCCESS  ▶ 0003 Built Successfully!
2018/12/12 12:57:18 INFO     ▶ 0004 Restarting 'goRedis'...
2018/12/12 12:57:18 SUCCESS  ▶ 0005 './goRedis' is running...
2018/12/12 12:57:18.909 [I] [asm_amd64.s:1333]  http server Running on http://:8080

然後去本機地址的8080埠載入一下頁面,好讓剛才編寫的程式碼能夠執行,從而向redis資料庫中寫入資料。

最後去終端redis資料庫中檢視內容變化。

127.0.0.1:6379> keys *
“frankName”
“frankAge”

127.0.0.1:6379> get frankName
frank

127.0.0.1:6379> get frankAge
18

因為send方法操作過於繁瑣,而讀取資料操作是同樣的道理,所以省略。

3.4 使用do方法對redis資料庫讀寫資料

在IDE中新增do方法程式碼,然後儲存等待熱更新完成,去頁面重新整理保證程式碼重新執行一次。

此時去終端檢視redis資料庫中內容,能夠證明新增成功

127.0.0.1:6379> keys *
“frankName”
“frankAge”
“frankGender”

127.0.0.1:6379> get frankGender
male

而後將新增內容程式碼註釋,轉而編輯下列程式碼來進行讀取操作。重複上述步驟。

在IDE的控制檯中能夠看到伺服器的輸出結果是:

3.5 使用Scan介面和Values介面操作多條不同型別資料

需要說明多條不同型別資料指的是在go語言中有多條不同型別資料被存入redis中,但是進入redis內部的時候必須都轉換成string字串格式。當然從redis中將資料取出來的時候依然需要轉換回資料原來的格式。為了方便測試具體程式碼效果,我先行清空了redis資料庫中前面幾條程式碼寫入進去的資料。

很顯然仍然是redis標準型別的操作語句mset,添加了一個字串和一個int型別進入redis。在redis中檢視能夠看到輸出內容是:

127.0.0.1:6379> keys *
“frankName”
“frankAge”

127.0.0.1:6379> get frankName
frank

127.0.0.1:6379> get frankAge
18

然後嘗試從程式碼中讀取資料

發現問題通過簡單的Do方法難以解決,於是藉助Values介面和Scan介面來實現。特別注意Scan掃描的資料型別僅僅能夠支援常見基本資料型別例如int string bool,而對於複雜資料型別則不能夠生效。

在IDE的控制檯中能夠看到伺服器的輸出結果是:

3.6 通過序列化與反序列化方法對redis資料庫進行復雜資料的讀寫操作

前文已經提到了go語言中通過使用Scan介面和Values介面能夠對基本資料進行redis的存取,但是這種操作對於複雜資料型別卻無能為力。但是實際開發中複雜資料型別的存取操作必然是重點,因此可以通過序列化和反序列化的方法來幫助進行復雜資料型別的操作。序列化和反序列化的方法被新增在了“encoding/gob”包裡面。


  • 序列化方法:gob.NewEncoder(序列化內容儲存容器 bytes.Buffer).Encode(需要被序列化的複雜資料型別)
  • 反序列化方法:gob.NewDecoder(bytes.NewReader(要被反序列化的加密字串)).Decode(&接收復雜資料型別的容器)
stuList := []string{"xiaohong","xiaohuang","xiaolan","xiaolv","xiaobai"}
var buffer bytes.Buffer
gob.NewEncoder(&buffer).Encode(stuList)
conn.Do("set","stuList",buffer.Bytes())

上述程式碼通過【gob.NewEncoder(&buffer).Encode(stuList)】語句將切片stuList這個複雜資料型別轉換成為了位元組流存入到了buffer變數內,因為位元組流本質就是字串,所以就可以通過do方法將對應資料儲存進入redis了。此時去redis資料庫檢視結果。

127.0.0.1:6379> keys *
stuList
127.0.0.1:6379> get stuList

????
    .?xiaohong	xiaohuangxiaolanxiaolvxiaobai

而與gob的序列化方式不同的是,反序列化的工作原理剛好相反:【序列化是將已知內容轉換為位元組流放到序列化容器內,反序列化是將位元組流轉換為原本資料型別放到反序列化容器內】。所以序列化的時候Encode中的引數用來存放序列化之後的位元組流,而反序列化的時候Decode中的引數卻是用來存放反序列化之後的資料。因為此時就不需要關心反序列化的資料究竟是什麼資料型別了,因為序列化之前資料是什麼型別,反序列化之後資料必然與之相同。

//建立接收資料容器
tempStu := []string{}

//從redis中獲取stuList欄位內容,並將字串通過轉換指令介面轉換為位元組流
reply,_:=redis.Bytes(conn.Do("get","stuList"))

//反序列化
byteReader := bytes.NewReader(reply)
gob.NewDecoder(byteReader).Decode(&tempStu)

//輸出反序列化結果tempStu
beego.Info(tempStu)

結果顯而易見,標準的切片型別。