PostgreSQL 是一個自由的對象-關系數據庫服務器(數據庫管理系統),它在靈活的 BSD-風格許可證下發行。它提供了相對其他開放源代碼數據庫系統(比如 MySQL 和 Firebird),和對專有系統比如 Oracle、Sybase、IBM 的 DB2 和 Microsoft SQL Server的一種選擇。
PostgreSQL和MySQL比較,它更加龐大一點,因為它是用來替代Oracle而設計的。所以在企業應用中采用PostgreSQL是一個明智的選擇。
MySQL被Oracle收購之后正在逐步的封閉(自MySQL 5.5.31以后的所有版本將不再遵循GPL協議),鑒于此,將來我們也許會選擇PostgreSQL而不是MySQL作為項目的后端數據庫。
## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/05.4.md#驅動)驅動
Go實現的支持PostgreSQL的驅動也很多,因為國外很多人在開發中使用了這個數據庫。
* [https://github.com/lib/pq](https://github.com/lib/pq)?支持database/sql驅動,純Go寫的
* [https://github.com/jbarham/gopgsqldriver](https://github.com/jbarham/gopgsqldriver)?支持database/sql驅動,純Go寫的
* [https://github.com/lxn/go-pgsql](https://github.com/lxn/go-pgsql)?支持database/sql驅動,純Go寫的
在下面的示例中我采用了第一個驅動,因為它目前使用的人最多,在github上也比較活躍。
## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/05.4.md#實例代碼)實例代碼
數據庫建表語句:
~~~
CREATE TABLE userinfo
(
uid serial NOT NULL,
username character varying(100) NOT NULL,
departname character varying(500) NOT NULL,
Created date,
CONSTRAINT userinfo_pkey PRIMARY KEY (uid)
)
WITH (OIDS=FALSE);
CREATE TABLE userdeatail
(
uid integer,
intro character varying(100),
profile character varying(100)
)
WITH(OIDS=FALSE);
~~~
看下面這個Go如何操作數據庫表數據:增刪改查
package main
~~~
import (
"database/sql"
"fmt"
_ "https://github.com/lib/pq"
)
func main() {
db, err := sql.Open("postgres", "user=astaxie password=astaxie dbname=test sslmode=disable")
checkErr(err)
//插入數據
stmt, err := db.Prepare("INSERT INTO userinfo(username,departname,created) VALUES($1,$2,$3) RETURNING uid")
checkErr(err)
res, err := stmt.Exec("astaxie", "研發部門", "2012-12-09")
checkErr(err)
//pg不支持這個函數,因為他沒有類似MySQL的自增ID
id, err := res.LastInsertId()
checkErr(err)
fmt.Println(id)
//更新數據
stmt, err = db.Prepare("update userinfo set username=$1 where uid=$2")
checkErr(err)
res, err = stmt.Exec("astaxieupdate", 1)
checkErr(err)
affect, err := res.RowsAffected()
checkErr(err)
fmt.Println(affect)
//查詢數據
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)
}
//刪除數據
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)
db.Close()
}
func checkErr(err error) {
if err != nil {
panic(err)
}
}
~~~
從上面的代碼我們可以看到,PostgreSQL是通過`$1`,`$2`這種方式來指定要傳遞的參數,而不是MySQL中的`?`,另外在sql.Open中的dsn信息的格式也與MySQL的驅動中的dsn格式不一樣,所以在使用時請注意它們的差異。
還有pg不支持LastInsertId函數,因為PostgreSQL內部沒有實現類似MySQL的自增ID返回,其他的代碼幾乎是一模一樣。
- 第一章 Go環境配置
- 1.1 Go安裝
- 1.2 GOPATH 與工作空間
- 1.3 Go 命令
- 1.4 Go開發工具
- 1.5 小結
- 第二章 Go語言基礎
- 2.1 你好,Go
- 2.2 Go基礎
- 2.3 流程和函數
- 2.4 struct類型
- 2.5 面向對象
- 2.6 interface
- 2.7 并發
- 2.8 總結
- 第三章 Web基礎
- 3.1 Web工作方式
- 3.2 Go搭建一個Web服務器
- 3.3 Go如何使得Web工作
- 3.4 Go的http包詳解
- 3.5 小結
- 第四章 表單
- 4.1 處理表單的輸入
- 4.2 驗證表單的輸入
- 4.3 預防跨站腳本
- 4.4 防止多次遞交表單
- 4.5 處理文件上傳
- 4.6 小結
- 第五章 訪問數據庫
- 5.1 database/sql接口
- 5.2 使用MySQL數據庫
- 5.3 使用SQLite數據庫
- 5.4 使用PostgreSQL數據庫
- 5.5 使用beedb庫進行ORM開發
- 5.6 NOSQL數據庫操作
- 5.7 小結
- 第六章 session和數據存儲
- 6.1 session和cookie
- 6.2 Go如何使用session
- 6.3 session存儲
- 6.4 預防session劫持
- 6.5 小結
- 第七章 文本處理
- 7.1 XML處理
- 7.2 JSON處理
- 7.3 正則處理
- 7.4 模板處理
- 7.5 文件操作
- 7.6 字符串處理
- 7.7 小結
- 第八章 Web服務
- 8.1 Socket編程
- 8.2 WebSocket
- 8.3 REST
- 8.4 RPC
- 8.5 小結
- 第九章 安全與加密
- 9.1 預防CSRF攻擊
- 9.2 確保輸入過濾
- 9.3 避免XSS攻擊
- 9.4 避免SQL注入
- 9.5 存儲密碼
- 9.6 加密和解密數據
- 9.7 小結
- 第十章 國際化和本地化
- 10.1 設置默認地區
- 10.2 本地化資源
- 10.3 國際化站點
- 10.4 小結
- 第十一章 錯誤處理,調試和測試
- 11.1 錯誤處理
- 11.2 使用GDB調試
- 11.3 Go怎么寫測試用例
- 11.4 小結
- 第十二章 部署與維護
- 12.1 應用日志
- 12.2 網站錯誤處理
- 12.3 應用部署
- 12.4 備份和恢復
- 12.5 小結
- 第十三章 如何設計一個Web框架
- 13.1 項目規劃
- 13.2 自定義路由器設計
- 13.3 controller設計
- 13.4 日志和配置設計
- 13.5 實現博客的增刪改
- 13.6 小結
- 第十四章 擴展Web框架
- 14.1 靜態文件支持
- 14.2 Session支持
- 14.3 表單及驗證支持
- 14.4 用戶認證
- 14.5 多語言支持
- 14.6 pprof支持
- 14.7 小結
- 附錄A 參考資料