Files
2019-06-17 06:52:04 +09:00

136 lines
3.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 5.4 使用PostgreSQL数据库
PostgreSQL 是一个自由的对象-关系数据库服务器(数据库管理系统),它在灵活的 BSD-风格许可证下发行。它提供了相对其他开放源代码数据库系统(比如 MySQL 和 Firebird),和对专有系统比如 Oracle、Sybase、IBM 的 DB2 和 Microsoft SQL Server的一种选择。
PostgreSQL和MySQL比较它更加庞大一点因为它是用来替代Oracle而设计的。所以在企业应用中采用PostgreSQL是一个明智的选择。
MySQL被Oracle收购之后正在逐步的封闭自MySQL 5.5.31以后的所有版本将不再遵循GPL协议鉴于此将来我们也许会选择PostgreSQL而不是MySQL作为项目的后端数据库。
## 驱动
Go实现的支持PostgreSQL的驱动也很多因为国外很多人在开发中使用了这个数据库。
- https://github.com/lib/pq 支持database/sql驱动纯Go写的
- https://github.com/jbarham/gopgsqldriver 支持database/sql驱动纯Go写的
- https://github.com/lxn/go-pgsql 支持database/sql驱动纯Go写的
在下面的示例中我采用了第一个驱动因为它目前使用的人最多在GitHub上也比较活跃。
## 实例代码
数据库建表语句:
```sql
CREATE TABLE userinfo
(
uid serial NOT NULL,
username character varying(100) NOT NULL,
department character varying(500) 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);
```
看下面这个Go如何操作数据库表数据:增删改查
```Go
package main
import (
"database/sql"
"fmt"
_ "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,department,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)
var lastInsertId int
err = db.QueryRow("INSERT INTO userinfo(username,departname,created) VALUES($1,$2,$3) returning uid;", "astaxie", "研发部门", "2012-12-09").Scan(&lastInsertId)
checkErr(err)
fmt.Println("最后插入id =", lastInsertId)
//更新数据
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返回其他的代码几乎是一模一样。
## links
* [目录](<preface.md>)
* 上一节: [使用SQLite数据库](<05.3.md>)
* 下一节: [使用Beego orm库进行ORM开发](<05.5.md>)