目录
一、 引言
1.1 PostgreSQL与MYSQL
1.2 Golang支持PostgreSQl驱动
二、编码实践
2.1 建表语句
2.2 CRUD代码
2.3 验证结果
三、结语
PostgreSQl是一个自由的对象——关系型数据库服务器(数据库管理系统)。同时,它也是除了开源数据库系统(如Mysql和Firebird)和专有系统(如Oracle、Sybase、IBM的DB2和Microsoft SQL Server)外的一种选择。
PostgreSQL和Mysql相比较,它更加庞大一些,因为它设计初衷就是用来替代Oracle的,所以在企业应用中采用PostgreSQL也是一种不错的选择。
自从Mysql被Oracle收购以后正在逐步封闭(自MYSQL 5.5.31以后的所有版本将不再遵守GPL协议)。也许将来会有更多的人选择PostgreSQL,而不是将Mysql作为项目的后端数据库。
Golang实现的支持PostgreSQL的驱动很多,毕竟很多外国人在开发中使用了PostgreSQL。以下将列出驱动:
- https://github.com/lib/pqhttps://github.com/lib/pq 支持database/sql驱动,纯Golang语言编写
- GitHub - jbarham/gopgsqldriver: PostgreSQL driver for the Go SQL database packagePostgreSQL driver for the Go SQL database package. Contribute to jbarham/gopgsqldriver development by creating an account on GitHub.https://github.com/jbarham/gopgsqldriver 支持database/sql驱动,纯Golang语言编写
- GitHub - lxn/go-pgsql: A PostgreSQL client package for the Go Programming LanguageA PostgreSQL client package for the Go Programming Language - GitHub - lxn/go-pgsql: A PostgreSQL client package for the Go Programming Languagehttps://github.com/lxn/go-pgsql 支持database/sql,纯Golang语言编写
本文中将使用第一个驱动,目前使用它的人最多,且在github上更活跃。
CREATE TABLE "public"."person" (
"id" int8 NOT NULL DEFAULT nextval('user_id_seq'::regclass),
"name" varchar(255) COLLATE "pg_catalog"."default",
"depart_name" varchar(255) COLLATE "pg_catalog"."default",
"create_at" date
)
可以看见我的数据库名叫 postgres, 表名叫 person
package main
import (
"database/sql"
"fmt"
_ "github.com/lib/pq"
)
type User struct {
id int64
name string
departName string
createAt string
}
func main() {
db, err := sql.Open("postgres", "host=192.168.58.128 port=5432 user=postgres password=password dbname=postgres sslmode=disable")
checkErr(err)
personId := insertUserReturnId(db)
insertUser(db)
updateUser(db, personId)
user := queryUser(db, personId)
fmt.Println("查询结果", user)
deleteUser(db, personId)
db.Close()
}
// 新增用户
func insertUserReturnId(db *sql.DB) (personId int) {
var lastInsertId int
db.QueryRow("insert into person(name,depart_name,create_at) values($1,$2,$3) returning id;", "朱八", "公关部", "2000-10-10").Scan(&lastInsertId)
fmt.Println("插入返回的主键id=", lastInsertId)
return lastInsertId
}
// 新增用户不返回id
func insertUser(db *sql.DB) {
stmt, err := db.Prepare("insert into person(name,depart_name,create_at) values($1,$2,$3) returning id")
checkErr(err)
_, err = stmt.Exec("朱八2", "公关部2", "2000-10-10")
checkErr(err)
// postgresql没有类似Mysql的自增id,不支持以下函数(LastInsertId),可以注释掉以下三行代码
//id, err := res.LastInsertId()
//checkErr(err)
//fmt.Println("生成主键(不支持时,默认0)", id)
}
// 更新用户
func updateUser(db *sql.DB, personId int) {
stmt, err := db.Prepare("update person set name=$1 where id =$2")
checkErr(err)
res, err := stmt.Exec("朱八改", personId)
checkErr(err)
affected, err := res.RowsAffected()
checkErr(err)
fmt.Println("更改数据作用数->", affected)
}
// 查询用户
func queryUser(db *sql.DB, personId int) (result []User) {
rows, err := db.Query("select name,depart_name,create_at,id from person where id =$1", personId)
checkErr(err)
users := []User{}
for rows.Next() {
user := User{}
err := rows.Scan(&user.name, &user.departName, &user.createAt, &user.id)
checkErr(err)
users = append(users, user)
fmt.Println("循环查询打印的值=>", user)
}
return users
}
// 删除用户
func deleteUser(db *sql.DB, personId int) {
stmt, err := db.Prepare("delete from person where id=$1")
checkErr(err)
res, err := stmt.Exec(personId)
checkErr(err)
affected, err := res.RowsAffected()
checkErr(err)
fmt.Println("删除作用数", affected)
}
func checkErr(err error) {
if err != nil {
panic(err)
}
}
- Mysql传参用的是 ?,而PostgreSQL通过$1、$2、$3方式制定要传递的参数。
- sql.open中 dataSourceName也与Mysql的不同。
- 由于PostgreSQL不支持LastInsertId函数,所以无法在stmt.Exec执行后返回res的自增id。
- 不用链接时注意关闭db.