Files
build-web-application-with-…/ru/05.4.md
2017-05-30 11:22:13 +08:00

128 lines
4.8 KiB
Markdown
Raw 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 - свободная объектно-реляционная система управления базами данных доступная для множества платформ, включая Linux, FreeBSD, Solaris, Microsoft Windows и Mac OS X. Выпускается под собственной MIT-подобной лицензией. В отличие от MySQL, она разработана и позиционируется для использования в корпоративном сегменте, как Oracle. Так что PostgreSQL - это хороший выбор для использования в корпоративных проектах.
## Драйвера PostgreSQL
Есть множество драйверов баз данных для 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.
Я буду использовать первый драйвер в последующих примерах.
##Примеры
Создайте таблицу следующим запросом:
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);
Пример:
package main
import (
"database/sql"
"fmt"
"time"
_ "github.com/lib/pq"
)
const (
DB_USER = "postgres"
DB_PASSWORD = "postgres"
DB_NAME = "test"
)
func main() {
dbinfo := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable",
DB_USER, DB_PASSWORD, DB_NAME)
db, err := sql.Open("postgres", dbinfo)
checkErr(err)
defer db.Close()
fmt.Println("# Inserting values")
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("last inserted id =", lastInsertId)
fmt.Println("# Updating")
stmt, err := db.Prepare("update userinfo set username=$1 where uid=$2")
checkErr(err)
res, err := stmt.Exec("astaxieupdate", lastInsertId)
checkErr(err)
affect, err := res.RowsAffected()
checkErr(err)
fmt.Println(affect, "rows changed")
fmt.Println("# Querying")
rows, err := db.Query("SELECT * FROM userinfo")
checkErr(err)
for rows.Next() {
var uid int
var username string
var department string
var created time.Time
err = rows.Scan(&uid, &username, &department, &created)
checkErr(err)
fmt.Println("uid | username | department | created ")
fmt.Printf("%3v | %8v | %6v | %6v\n", uid, username, department, created)
}
fmt.Println("# Deleting")
stmt, err = db.Prepare("delete from userinfo where uid=$1")
checkErr(err)
res, err = stmt.Exec(lastInsertId)
checkErr(err)
affect, err = res.RowsAffected()
checkErr(err)
fmt.Println(affect, "rows changed")
}
func checkErr(err error) {
if err != nil {
panic(err)
}
}
Обратите внимание, что PostgreSQL использует формат подстановки вида `$1,$2`, в отличие от MySQL, который использует `?`, а так же используется другой формат DSN при вызове `sql.Open`.
Так же, имейте в виду, что Postgres не поддерживает `sql.Result.LastInsertId()`.
Таким образом, вместо этого,
stmt, err := db.Prepare("INSERT INTO userinfo(username,departname,created) VALUES($1,$2,$3);")
res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
fmt.Println(res.LastInsertId())
используйте `db.QueryRow()` и `.Scan()` для получения значения идентификатора последней вставки.
err = db.QueryRow("INSERT INTO TABLE_NAME values($1) returning uid;", VALUE1").Scan(&lastInsertId)
fmt.Println(lastInsertId)
## Ссылки
- [Содержание](preface.md)
- Предыдущий раздел: [SQLite](05.3.md)
- Следующий раздел: [Разработка ORM на основе beedb](05.5.md)