一文學會Go語言數據庫操作
對許多 Web 應用程序而言,數據庫都是其核心所在。數據庫幾乎可以用來存儲想查詢和修改的任何信息,比如用戶信息、產品目錄或者新聞列表等。
數據庫是Web編程不可或缺的主題。這里我們就來看一下如何用 Go 語言操作不同的數據庫。
database/sql 接口
Go 語言不同于 PHP,它沒有官方提供任何數據庫驅動,而是為開發者定義了一組標準接口。提供數據庫服務的開發者,可以實現這組接口,以為特定的數據提供驅動。而數據庫的使用者,也可以通過這組接口方便地訪問數據庫,甚至在適當的時候,以非常小的代價遷移數據庫。
通常我們在以類似如下的方式導入數據庫驅動模塊時:
import _ "github.com/Go-SQL-Driver/MySQL"
上面的 import 語句中的下劃線表示,我們要導入這個模塊,但不會直接使用其中的符號。但導入的時候,會執行模塊的初始化代碼,也就是其中定義的 init() 函數,在這個函數中數據庫驅動會自動將其自身注冊進 Go 的 database/sql 框架中,后面我們就可以方便地通過這個接口來訪問對應得數據了。
關于這組接口的詳細內容,可以參考 官方文檔 。
MySQL
目前網上流行的網站架構方式是 LAMP,其中的 M 即為 MySQL。作為數據庫,MySQL 以免費、開源、使用方便為優勢而成為了許多Web開發的后端數據庫存儲引擎。
MySQL 安裝
首先我們需要安裝 MySQL,這可以通過如下的命令來完成:
$ sudo apt install mysql-server
$ sudo apt-get install mysql-client
$ mysql_secure_installation
安裝之后,通過如下命令可以查看 MySQL 服務器占用的端口:
$ sudo lsof -i -P
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
. . . . . .
mysqld 17860 mysql 20u IPv4 136588 0t0 TCP localhost:3306 (LISTEN)
可以看到 MySQL 服務器在 TCP 的 3306 端口監聽請求。
新MySQL建用戶
安裝好了 MySQL 之后,我們還需要創建用戶,以便于后面在代碼里使用。創建用戶的方法如下:
## 登錄MYSQL
$ mysql -u root -p
Enter password:
## 創建用戶
mysql> CREATE USER 'hanpfei'@'localhost' IDENTIFIED BY 'hanpfei';
## 刷新系統權限表
mysql>flush privileges;
這樣就創建了一個名為 hanpfei ,密碼為 hanpfei 的用戶。
然后登錄一下。
mysql> exit;
$ mysql -u hanpfei -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 5.7.17-0ubuntu0.16.04.1 (Ubuntu)
. . . . . .
mysql>
創建數據庫并為用戶授權
登錄MYSQL(有ROOT權限)。我里我以 ROOT 身份登錄.
$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 5.7.17-0ubuntu0.16.04.1 (Ubuntu)
為用戶創建一個數據庫 ( staff_info_db )
mysql>create database staff_info_db;
授權 hanpfei 用戶擁有 staff_info_db 數據庫的所有權限。
mysql>grant all privileges on staff_info_db.* to hanpfei@localhost identified by 'hanpfei';
刷新系統權限表
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
創建表
有了數據庫,接下來就是創建表了。建表語句如下:
CREATE TABLE `userinfo1` (
`uid` INT(10) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(64) NULL DEFAULT NULL,
`departname` VARCHAR(64) NULL DEFAULT NULL,
`created` DATE NULL DEFAULT NULL,
PRIMARY KEY (`uid`)
);
CREATE TABLE `userdetail` (
`uid` INT(10) NOT NULL DEFAULT '0',
`intro` TEXT NULL,
`profile` TEXT NULL,
PRIMARY KEY (`uid`)
);
具體的建表可以通過如下得命令來完成:
$ mysql -u hanpfei -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 18
Server version: 5.7.17-0ubuntu0.16.04.1 (Ubuntu)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use staff_info_db;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> CREATE TABLE `userinfo` (
-> `uid` INT(10) NOT NULL AUTO_INCREMENT,
-> `username` VARCHAR(64) NULL DEFAULT NULL,
-> `departname` VARCHAR(64) NULL DEFAULT NULL,
-> `created` DATE NULL DEFAULT NULL,
-> PRIMARY KEY (`uid`)
-> );
Query OK, 0 rows affected (0.80 sec)
mysql> CREATE TABLE `userdetail` (
-> `uid` INT(10) NOT NULL DEFAULT '0',
-> `intro` TEXT NULL,
-> `profile` TEXT NULL,
-> PRIMARY KEY (`uid`)
-> );
Query OK, 0 rows affected (0.80 sec)
mysql> exit
Bye
這樣我們需要的表就建好了。
用 Go 語言訪問 MySQL
安裝好了數據庫,并創建了適當的用戶、數據庫以及數據庫表之后,我們就可以開始用 Go 語言訪問 MySQL了。然而,在實際寫代碼之前,還要先下載對應的驅動。Go 語言中支持 MySQL 的驅動目前比較多,我們以支持 Go 語言標準 database/sql 接口的 github.com/Go-SQL-Driver/MySQL 為例來看。我們先要下載這個包:
$ go get github.com/Go-SQL-Driver/MySQL
然后來看如何使用 database/sql 接口對數據庫表進行增刪改查操作:
package main
import (
_ "github.com/Go-SQL-Driver/MySQL"
"fmt"
"database/sql"
)
func checkErr(err error) {
if err != nil {
panic(err)
}
}
func mysqlTest() {
db, err := sql.Open("mysql", "hanpfei:hanpfei@/staff_info_db?charset=utf8")
checkErr(err)
defer db.Close()
// Insert
stmt, err := db.Prepare("INSERT userinfo SET username=?,departname=?,created=?")
checkErr(err)
res, err := stmt.Exec("hanpfei", "R&D Department", "2016-05-23")
checkErr(err)
id, err := res.LastInsertId()
checkErr(err)
fmt.Println(id)
// Update
stmt, err = db.Prepare("UPDATE userinfo SET username=? where uid=?")
checkErr(err)
res, err = stmt.Exec("hanpfeiupdate", id)
checkErr(err)
affect, err := res.RowsAffected()
checkErr(err)
fmt.Println(affect)
// Query
rows, err := db.Query("SELECT * FROM userinfo")
checkErr(err)
for rows.Next() {
var uid int
var username string
var department string
var created string
err = rows.Scan(&uid, &username, &department, & created)
checkErr(err)
fmt.Println(uid)
fmt.Println(username)
fmt.Println(department)
fmt.Println(created)
}
// Delete data
stmt, err = db.Prepare("DELETE from userinfo where uid=?")
checkErr(err)
res, err = stmt.Exec(id)
checkErr(err)
affect, err = res.RowsAffected()
checkErr(err)
fmt.Println(affect)
checkErr(err)
}
func main() {
mysqlTest()
}
通過以上代碼,可以看出來 Go 語言操作 MySQL 數據庫還是非常方便的。關于這個數據庫驅動的用法更詳細的信息,可以參考其 官方文檔 。
SQLite3
SQLite 是一個開源的嵌入式系統的關系型數據庫,它是實現自包容、零配置且支持事務的 SQL 數據庫引擎。其特點是高度便攜、結構緊湊、高效且可靠。與其它許多數據庫相比,SQLite 的安裝運行都非常簡單。大多數情況下,只要確保 SQLite 的二進制文件存在,即可創建和訪問數據庫。
可以通過如下的命令來安裝 SQLite:
$ sudo apt-get install libsqlite3-0 libsqlite3-dev
SQLite 的命令行工具可裝可不裝,不影響我們通過代碼操作 SQLite 數據庫。
同樣我們需要選擇一款 SQLite 驅動。Go 語言支持 SQLite 的驅動也比較多,但好多都不支持 database/sql 接口。這里我們選擇支持 database/sql 接口的 github.com/mattn/go-sqlite3 。
在開始寫代碼前,要先安裝這個驅動:
$ go get github.com/mattn/go-sqlite3
建表的語句如下:
CREATE TABLE `userinfo` (
`uid` INTEGER PRIMARY KEY AUTOINCREMENT,
`username` VARCHAR(64) NULL,
`departname` VARCHAR(64) NULL,
`created` DATE NULL
);
CREATE TABLE `userdetail` (
`uid` INT(10) NULL,
`intro` TEXT NULL,
`profile` TEXT NULL,
PRIMARY KEY (`uid`)
);
不過我們同樣通過代碼來完成建表了。然后來看在 Go 語言中,具體如何操作 SQLite :
package main
import (
_ "github.com/mattn/go-sqlite3"
"database/sql"
"fmt"
)
func checkErr(err error) {
if err != nil {
panic(err)
}
}
func testOperationForSqlite3(db *sql.DB) {
// Insert
stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, created) values(?,?,?)")
checkErr(err)
res, err := stmt.Exec("hanpfei", "R&D Department", "2016-05-23")
checkErr(err)
id, err := res.LastInsertId()
checkErr(err)
fmt.Println(id)
// Update
stmt, err = db.Prepare("UPDATE userinfo SET username=? where uid=?")
checkErr(err)
res, err = stmt.Exec("hanpfeiupdate", id)
checkErr(err)
affect, err := res.RowsAffected()
checkErr(err)
fmt.Println(affect)
// Query
rows, err := db.Query("SELECT * FROM userinfo")
checkErr(err)
for rows.Next() {
var uid int
var username string
var department string
var created string
err = rows.Scan(&uid, &username, &department, & created)
checkErr(err)
fmt.Println(uid)
fmt.Println(username)
fmt.Println(department)
fmt.Println(created)
}
// Delete data
stmt, err = db.Prepare("DELETE from userinfo where uid=?")
checkErr(err)
res, err = stmt.Exec(id)
checkErr(err)
affect, err = res.RowsAffected()
checkErr(err)
fmt.Println(affect)
checkErr(err)
}
func createTableForSqlite3(db *sql.DB) {
createTableCommand := "CREATE TABLE userinfo (uid INTEGER PRIMARY KEY AUTOINCREMENT, username VARCHAR(64) NULL, " +
"departname VARCHAR(64) NULL, created DATE NULL);"
stmt, err := db.Prepare(createTableCommand)
checkErr(err)
_, err = stmt.Exec()
checkErr(err)
createTableCommand = "CREATE TABLE userdetail (uid INT(10) NULL, intro TEXT NULL, profile TEXT NULL, PRIMARY KEY (uid));"
stmt, err = db.Prepare(createTableCommand)
checkErr(err)
_, err = stmt.Exec()
checkErr(err)
}
func sqlite3Test() {
db, err := sql.Open("sqlite3", "./foo.db")
checkErr(err)
defer db.Close()
createTableForSqlite3(db)
testOperationForSqlite3(db)
}
func main() {
sqlite3Test()
}
執行上面的代碼,將看到如下的輸出:
/usr/lib/go/bin/go run /home/hanpfei0306/IdeaProjects/HelloGo/Sqlite3.go
1
1
1
hanpfeiupdate
R&D Department
2016-05-23T00:00:00Z
1
Process finished with exit code 0
我們可以看到,上面操作 SQLite 數據庫的代碼,和前面操作 MySQL 數據庫的代碼幾乎一模一樣。僅有的改變是導入的驅動變了,然后調用 sql,Open() 打開數據庫驅動的方式不同。
PostgreSQL
PostgreSQL 是一個開源的自由的對象-關系數據庫服務器,它以靈活的 BSD-Style 許可發行。相對于其它許多的開源數據庫系統(如 MySQL 和 Firebird)和商業數據庫系統(如 Oracle 和 MS SQL Server),它為我們提供了另外的一種選擇。
PostgreSQL 相對于 MySQL 而言更加龐大,因為它本是為替代 Oracle 而設計。
這里我們就來看一下如何用 Go 語言操作 PostgreSQL。
安裝
我們首先要安裝 PostgreSQL 服務器。使用如下命令,會自動安裝最新版,這里為 9.5 :
sudo apt-get install postgresql
安裝完成后,默認會:
(1)創建名為 “postgres” 的Linux用戶
(2)創建名為 “postgres”、不帶密碼的默認數據庫賬號作為數據庫管理員
(3)創建名為 “postgres” 的表
安裝完成后的一些默認信息如下:
config /etc/postgresql/9.5/main
data /var/lib/postgresql/9.5/main
locale en_US.UTF-8
socket /var/run/postgresql
port 5432
通過 lsof -i 命令我們可以查看 PostgreSQL 服務器占用的端口,并確認其在正常運行:
$ sudo lsof -i -P
. . . . . .
postgres 24581 postgres 6u IPv6284716 0t0 TCP localhost:5432 (LISTEN)
postgres 24581 postgres 7u IPv4284717 0t0 TCP localhost:5432 (LISTEN)
postgres 24581 postgres 11u IPv6279448 0t0 UDP localhost:42368->localhost:42368
postgres 24583 postgres 11u IPv6279448 0t0 UDP localhost:42368->localhost:42368
postgres 24584 postgres 11u IPv6279448 0t0 UDP localhost:42368->localhost:42368
postgres 24585 postgres 11u IPv6279448 0t0 UDP localhost:42368->localhost:42368
postgres 24586 postgres 11u IPv6279448 0t0 UDP localhost:42368->localhost:42368
postgres 24587 postgres 11u IPv6279448 0t0 UDP localhost:42368->localhost:42368
可以看到 PostgreSQL 服務器在 TCP 的 5432 端口上監聽請求,并開啟了多個進程來監聽。
配置
安裝完后會有 PostgreSQL 的客戶端 psql 可以用,通過 sudo -u postgres psql 進入,提示符變成 postgres=# :
$ sudo -u postgres psql
psql (9.5.6)
Type "help" for help.
postgres=#
在這里可以執行 SQL 語句和 psql 的基本命令。
新建 PostgreSQL用戶
我們可以通過如下的命令
postgres=# CREATE USER hanpfei PASSWORD 'hanpfei' CREATEDB;
CREATE ROLE
通過 \du 可以查看當前已經存在的用戶列表:
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
hanpfei | Create DB | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
此時我們以新創建的用戶登錄PostgreSQL,會報出如下得error:
$ sudo -u postgres psql -U hanpfei
psql: FATAL: Peer authentication failed for user "hanpfei"
我們可以通過修改 pg_hba.conf 文件來解決這個問題:
$ sudo gedit /etc/postgresql/9.5/main/pg_hba.conf
將其中 除 postgres 用戶外 的所有用戶的 METHOD 都從 peer 或 ident 改為 md5 或 trust 。
修改完畢,保存退出。
然后執行如下命令重新加載配置:
$ /etc/init.d/postgresql reload
再次嘗試用新創建的用戶的登錄 PostgreSQL 時報出了新的 error:
$ sudo -u postgres psql -U hanpfei
Password for user hanpfei:
psql: FATAL: database "hanpfei" does not exist
提示用戶的數據庫不存在。我們還需要再次登錄 postgres 用戶,為我們的新用戶創建數據庫:
$ sudo -u postgres psql
psql (9.5.6)
Type "help" for help.
postgres=# create database hanpfei;
CREATE DATABASE
postgres=# \q
然后就可以以新用戶登錄了:
$ sudo -u postgres psql -U hanpfei
[sudo] hanpfei0306 的密碼:
Password for user hanpfei:
psql (9.5.6)
Type "help" for help.
hanpfei=>
這里我們需要輸入兩次密碼,一次是當前 Linux 用戶的用戶密碼,用來執行 sudo,另一次是數據庫的用戶的密碼,用來登錄數據庫。
接著我們創建一個新的應用數據庫,并選擇它作為我們當前使用的數據庫,這可以通過 \c 命令來實現:
hanpfei=> \l
List of databases
Name |Owner|Encoding|Collate|Ctype|Access privileges
---------------+----------+----------+-------------+-------------+-----------------------
hanpfei |postgres|UTF8|zh_CN.UTF-8|zh_CN.UTF-8|
postgres |postgres|UTF8|zh_CN.UTF-8|zh_CN.UTF-8|
staff_info_db |hanpfei|UTF8|zh_CN.UTF-8|zh_CN.UTF-8|
template0 |postgres|UTF8|zh_CN.UTF-8|zh_CN.UTF-8|=c/postgres +
|||||postgres=CTc/postgres
template1 |postgres|UTF8|zh_CN.UTF-8|zh_CN.UTF-8|=c/postgres +
|||||postgres=CTc/postgres
(5 rows)
hanpfei=> create database staff_info_db;
hanpfei=> \c staff_info_db;
You are now connected to database "staff_info_db" as user "hanpfei".
staff_info_db=>
上面的 \l 是用來列出當前已創建的所有數據庫的。注意我們切換了數據庫之后,命令輸入提示字符串也變為了新數據庫的名字。
然后創建表。建表語句如下:
CREATE TABLE userinfo (
uid serial NOT NULL,
username character varying(100) NOT NULL,
departname character varying(100) NOT NULL,
created date,
CONSTRAINT userinfo_pkey PRIMARY KEY (uid)
)
WITH (OIDS=FALSE);
CREATE TABLE userdetail (
uid integer,
intro character varying(100),
profile character varying(100)
)
WITH (OIDS=FALSE);
具體命令則是:
staff_info_db=> CREATE TABLE userinfo (
staff_info_db(> uid serial NOT NULL,
staff_info_db(> username character varying(100) NOT NULL,
staff_info_db(> departname character varying(100) NOT NULL,
staff_info_db(> created date,
staff_info_db(> CONSTRAINT userinfo_pkey PRIMARY KEY (uid)
staff_info_db(> )
staff_info_db-> WITH (OIDS=FALSE);
CREATE TABLE
staff_info_db=> CREATE TABLE userdetail (
staff_info_db(> uid integer,
staff_info_db(> intro character varying(100),
staff_info_db(> profile character varying(100)
staff_info_db(> )
staff_info_db-> WITH (OIDS=FALSE);
CREATE TABLE
staff_info_db=>
權限
創建的表還可以賦予其它用戶完全的權限,比如,以 postgres 用戶創建的表的完全的權限賦予新用戶:
postgres=# GRANT ALL ON userinfo TO hanpfei;
postgres=# GRANT ALL ON userinfo TO userdetail;
使用 Go 語言操作 PostgreSQL
同樣我們需要先找個驅動。Go 語言的 PostgreSQL 驅動也很多。這里我們選用支持 database/sql 接口的驅動 github.com/lib/pq ,這個項目由 github.com/bmizerany/pq 遷移而來,而后者目前已經廢棄。我們還是要先安裝:
$ go get github.com/lib/pq
然后用 Go 語言訪問 PostgreSQL:
package main
import (
_ "github.com/lib/pq"
"fmt"
"database/sql"
)
func checkErr(err error) {
if err != nil {
panic(err)
}
}
func testOperationForPostgreSQL(db *sql.DB) {
// Insert
stmt, err := db.Prepare("INSERT INTO userinfo(username,departname,created) VALUES($1,$2,$3) RETURNING uid")
checkErr(err)
res, err := stmt.Exec("hanpfei", "R_D_Department", "2016-05-23")
checkErr(err)
// id, err := res.LastInsertId()
// checkErr(err)
fmt.Println(res)
// Update
stmt, err = db.Prepare("UPDATE userinfo SET username=$1 where uid=$2")
checkErr(err)
res, err = stmt.Exec("hanpfeiupdate", 1)
checkErr(err)
affect, err := res.RowsAffected()
checkErr(err)
fmt.Println(affect)
// Query
rows, err := db.Query("SELECT * FROM userinfo")
checkErr(err)
for rows.Next() {
var uid int
var username string
var department string
var created string
err = rows.Scan(&uid, &username, &department, & created)
checkErr(err)
fmt.Println(uid)
fmt.Println(username)
fmt.Println(department)
fmt.Println(created)
}
// Delete data
stmt, err = db.Prepare("DELETE from userinfo where uid=$1")
checkErr(err)
res, err = stmt.Exec(1)
checkErr(err)
affect, err = res.RowsAffected()
checkErr(err)
fmt.Println(affect)
checkErr(err)
}
func postgreSqlTest() {
db, err := sql.Open("postgres", "user=hanpfei password=hanpfei dbname=staff_info_db sslmode=disable")
checkErr(err)
defer db.Close()
testOperationForPostgreSQL(db)
}
func main() {
postgreSqlTest()
}
從上面的代碼中可以看到,PostgreSQL 是通過 “$1,$2”這種方式來占位要傳入的參數的,而不是 MySQL 中的 “?” 另外在 sql.Open() 中的 dsn 信息的格式也與 MySQL 不同,因而在使用時需要注意。
此外, PostgreSQL 不支持 LastInsertId() 函數,因為它內部沒有實現類似 MySQL 的自增 ID 返回。其它的代碼則幾乎一模一樣。
NoSQL 數據庫
NoSQL (Not only SQL),指的是非關系型數據庫。隨著 Web 2.0 的興起,傳統的關系型數據庫在應付新應用,特別是超大規模和高并發得 SNS 型 Web 2.0 純動態網站時已經顯得力不從心,暴露了很多難以客服得問題,而非關系型數據庫則由于其自身的有點,而得到迅速得發展。
在看了上面的幾種 SQL 數據庫之后,接下來我們將學習用 Go 語言操作幾種 NoSQL 數據庫,主要是 Redis 和 MongoDB。
Redis
Redis 是一個開源的(BSD 許可),基于內存的數據結構存儲產品,它可以被用作數據庫,緩存和消息代理。它支持的數據結構非常多,如 string(字符串),hash(哈希),list(列表),set(集合),帶有范圍查詢的sorted set(有序集合),bitmap(位圖),超文本和具有半徑查詢的地理空間索引。Redis具有內置復制,Lua腳本,LRU驅逐,事務和不同級別的磁盤持久性,并通過Redis Sentinel提供高可用性,并通過Redis Cluster進行自動分區。
Redis 是一個超高性能的 key-value 數據庫。Redis 的出現,很大程度補償了memcached 這類 key-value 存儲的不足,在部 分場合可以對關系數據庫起到很好的補充作用。它提供了Python,Ruby,Erlang,PHP客戶端,使用很方便。
這里我們就來看一下如何用 Go 語言操作Redis。
Redis 安裝
使用如下命令,會自動安裝最新版
$ sudo apt-get install redis-server redis-tools
通過 lsof -i 命令我們可以查看 Redis 服務器占用的端口。
$ sudo lsof -i -P
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
. . . . . .
redis-ser 2977 redis 4u IPv4 507101 0t0 TCP localhost:6379 (LISTEN)
可以看到 Redis 服務器在 TCP 的 6379 端口監聽請求。
Redis 還提供了功能強大的命令行工具
$ redis-cli
127.0.0.1:6379> help
redis-cli 3.0.6
Type: "help @<group>" to get a list of commands in <group>
"help <command>" for help on <command>
"help <tab>" to get a list of possible help topics
"quit" to exit
Go 程序訪問 Redis
Go 語言的 Redis 客戶端驅動還是很多的,具體可以通過 Redis 的 Client 頁 找到它們。當前還處于比較活躍的狀態,也就是近 6 個月官方 repo 有過更新的驅動如下:
https://github.com/go-redis/redis
https://github.com/keimoon/gore
https://github.com/gosexy/redis
https://github.com/tideland/golib
https://github.com/garyburd/redigo
https://github.com/mediocregopher/radix.v2
其中最后兩個,是目前 Redis 官方推薦使用的 Go 驅動。這里我們以最后一個為例,來看要如何在 Go 代碼里操作 Redis。然而,在開始之前,我們還是要先安裝相應的包:
$ go get github.com/mediocregopher/radix.v2/redis
接著來看具體如何通過 Go 語言訪問 Redis:
package main
import (
"fmt"
"github.com/mediocregopher/radix.v2/redis"
)
func checkErr(err error) {
if err != nil {
panic(err)
}
}
func testRedisWithRadix() {
client, err := redis.Dial("tcp", "localhost:6379")
checkErr(err)
err = client.Cmd("SET", "a", "hello").Err
checkErr(err)
val, err := client.Cmd("GET", "a").Str()
checkErr(err)
fmt.Println("Redis val:")
fmt.Println(string(val))
err = client.Cmd("DEL", "a").Err
checkErr(err)
// list operation
vals := []string{"a", "b", "c", "d", "e"}
for _, v := range vals {
err = client.Cmd("RPUSH", "l", v).Err
checkErr(err)
}
dbvals, err := client.Cmd("LRANGE", "l", 0, 4).List()
checkErr(err)
for i, v := range dbvals {
fmt.Println(i, ":", string(v))
}
err = client.Cmd("DEL", "l").Err
checkErr(err)
}
func main() {
testRedisWithRadix()
}
運行上面代碼,可以看到如下的輸出:
$ /usr/lib/go/bin/go run /home/hanpfei0306/IdeaProjects/HelloGo/Redis.go
Redis val:
hello
0 : a
1 : b
2 : c
3 : d
4 : e
Process finished with exit code 0
我們可以看到,操作 Redis 非常方便,大多只要用 client 命令即可。關于 Radix 用法的更多詳細內容,可以參考其 官方文檔 。
MongoDB
MongoDB 是一個高性能功能強大而流行的分布式文檔存儲 NoSQL (Not Only SQL) 數據庫產品。它是一個介于關系數據庫和非關系數據庫之間的產品,是非關系數據庫當中功能最豐富,最像關系數據庫的。他支持的數據結構非常松散,是類似json的bjson格式,因此可以存儲比較復雜的數據類型。Mongo最大的特點是他支持的查詢語言非常強大,其語法有點類似于面向對象的查詢語言,幾乎可以實現類似關系數據庫單表查詢的絕大部分功能,而且還支持對數據建立索引。
下面我們來看一下如何通過 Go 語言操作 MongoDB。
MongoDB 安裝
首先需要安裝 MongoDB。使用如下命令,會自動安裝最新版 MongoDB,這里是 2.6.10 版。
$ sudo apt-get install mongodb mongodb-clients mongodb-server
通過 lsof -i 命令我們可以查看 MongoDB 服務器占用的端口,并確認 MongoDB 服務器的正常運行。
sudo lsof -i -P
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
. . . . . .
mongod 7838 mongodb 8u IPv4 536811 0t0 TCP localhost:27017 (LISTEN)
可以看到 MongoDB 服務器在 TCP 的 27017 端口監聽請求。
創建數據庫
安裝了 MongoDB 服務器之后,我們還要創建數據庫,以備后面在代碼里面用。我們可以通過 MongoDB 的 shell 版本,使用 use 命令創建數據庫:
$ mongo
MongoDB shell version: 2.6.10
connecting to: test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
> use people_info
switched to db people_info
use 命令在 MySQL 中用于選擇已經創建好的數據庫,而在 MongoDB 中則會自動創建當前還不存在的數據庫。
Go 程序訪問 MongoDB
在開始編寫 Go 代碼訪問 MongoDB 數據庫之前,我們還要先下載 MongoDB 的Go語言驅動。在 MongoDB 的 官方 Drivers主頁 可以找到可用的 Go 語言驅動。當前官方推薦的只有開源社區支持的 mgo 驅動。 mgo 主頁 。mgo 的 GitHub 主頁 。通過 go get 命令安裝我們需要的兩個 mgo Go 包:
$ go get gopkg.in/mgo.v2
$ go get gopkg.in/mgo.v2/bson
接著來看具體如何通過 Go 語言操作 MongoDB。
package main
import (
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"fmt"
)
type Person struct {
Name string
Phone string
}
funccheckErr(err error) {
if err != nil {
panic(err)
}
}
functestMongoDB() {
session, err := mgo.Dial("localhost")
checkErr(err)
defer session.Close()
session.SetMode(mgo.Monotonic, true)
c := session.DB("people_info").C("people")
err = c.Insert(&Person{"Ale", "+55 53 8116 9639"},
&Person{"Cla", "+55 53 8402 8510"})
checkErr(err)
result := Person{}
err = c.Find(bson.M{"name": "Ale"}).One(&result)
checkErr(err)
fmt.Println("Phone:", result.Phone)
}
funcmain() {
testMongoDB()
}
操作與許多 SQL數據庫的 ORM 庫提供的很相似,可以直接操作對象。
來自:https://www.wolfcstech.com/2017/02/26/一文學會Go語言數據庫操作/