目录
一、 引言
1.1 PostgreSQL与MYSQL
1.2 Golang支持PostgreSQl驱动
二、编码实践
2.1 建表语句
2.2 CRUD代码
2.3 验证结果
三、结语
一、 引言
1.1 PostgreSQL与MYSQL
PostgreSQl是一个自由的对象——关系型数据库服务器(数据库管理系统)。同时,它也是除了开源数据库系统(如Mysql和Firebird)和专有系统(如Oracle、Sybase、IBM的DB2和Microsoft SQL Server)外的一种选择。
PostgreSQL和Mysql相比较,它更加庞大一些,因为它设计初衷就是用来替代Oracle的,所以在企业应用中采用PostgreSQL也是一种不错的选择。
自从Mysql被Oracle收购以后正在逐步封闭(自MYSQL 5.5.31以后的所有版本将不再遵守GPL协议)。也许将来会有更多的人选择PostgreSQL,而不是将Mysql作为项目的后端数据库。
1.2 Golang支持PostgreSQl驱动
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上更活跃。
二、编码实践2.1 建表语句
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
2.2 CRUD代码
package mainimport ("database/sql""fmt"_ "github.com/lib/pq"
)type User struct {id int64name stringdepartName stringcreateAt 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 intdb.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)}
}
2.3 验证结果
三、结语
- Mysql传参用的是 ?,而PostgreSQL通过$1、$2、$3方式制定要传递的参数。
- sql.open中 dataSourceName也与Mysql的不同。
- 由于PostgreSQL不支持LastInsertId函数,所以无法在stmt.Exec执行后返回res的自增id。
- 不用链接时注意关闭db.