golang PostgreSQL数据库驱动插件库pq的使用
golang PostgreSQL数据库驱动插件库pq的使用
安装
go get github.com/lib/pq
特性
- SSL支持
- 处理
database/sql
的不良连接 - 正确扫描
time.Time
类型(如timestamp[tz]
,time[tz]
,date
) - 正确扫描二进制blob(如
bytea
) - 支持
hstore
包 - 支持COPY FROM
- pq.ParseURL用于将URL转换为sql.Open的连接字符串
- 许多与libpq兼容的环境变量
- Unix套接字支持
- 通知:
LISTEN
/NOTIFY
- pgpass支持
- GSS(Kerberos)认证
完整示例demo
下面是一个使用pq连接PostgreSQL数据库并进行基本CRUD操作的完整示例:
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/lib/pq"
)
const (
host = "localhost"
port = 5432
user = "postgres"
password = "yourpassword"
dbname = "testdb"
)
func main() {
// 构建连接字符串
psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
"password=%s dbname=%s sslmode=disable",
host, port, user, password, dbname)
// 打开数据库连接
db, err := sql.Open("postgres", psqlInfo)
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 测试连接
err = db.Ping()
if err != nil {
log.Fatal(err)
}
fmt.Println("Successfully connected!")
// 创建表
createTableSQL := `
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username TEXT NOT NULL,
email TEXT NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);`
_, err = db.Exec(createTableSQL)
if err != nil {
log.Fatal(err)
}
fmt.Println("Table created successfully")
// 插入数据
insertSQL := `
INSERT INTO users (username, email)
VALUES ($1, $2)
RETURNING id`
id := 0
err = db.QueryRow(insertSQL, "john_doe", "john@example.com").Scan(&id)
if err != nil {
log.Fatal(err)
}
fmt.Println("New record ID is:", id)
// 查询数据
rows, err := db.Query("SELECT id, username, email FROM users")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
fmt.Println("Query results:")
for rows.Next() {
var id int
var username, email string
err = rows.Scan(&id, &username, &email)
if err != nil {
log.Fatal(err)
}
fmt.Printf("ID: %d, Username: %s, Email: %s\n", id, username, email)
}
// 更新数据
updateSQL := `UPDATE users SET username = $1 WHERE id = $2`
_, err = db.Exec(updateSQL, "john_doe_updated", id)
if err != nil {
log.Fatal(err)
}
fmt.Println("Record updated successfully")
// 删除数据
deleteSQL := `DELETE FROM users WHERE id = $1`
_, err = db.Exec(deleteSQL, id)
if err != nil {
log.Fatal(err)
}
fmt.Println("Record deleted successfully")
}
状态
这个包目前处于维护模式,这意味着:
- 通常不接受新功能
- 接受社区提供的错误修复和版本兼容性更改
- 维护者通常不解决报告的问题
- 鼓励社区成员互相帮助解决报告的问题
对于需要新功能或可靠解决报告错误的用户,我们推荐使用pgx,它正在积极开发中。
更多关于golang PostgreSQL数据库驱动插件库pq的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang PostgreSQL数据库驱动插件库pq的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang PostgreSQL 数据库驱动 pq 使用指南
pq 是 Go 语言中最流行的 PostgreSQL 数据库驱动之一,它实现了 database/sql 接口,提供了稳定可靠的 PostgreSQL 数据库连接功能。
安装 pq 驱动
go get github.com/lib/pq
基本使用
1. 连接数据库
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/lib/pq"
)
func main() {
// 连接字符串格式: "postgres://用户名:密码@主机:端口/数据库名?sslmode=disable"
connStr := "user=postgres password=yourpassword dbname=testdb sslmode=disable"
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 测试连接
err = db.Ping()
if err != nil {
log.Fatal(err)
}
fmt.Println("Successfully connected to PostgreSQL!")
}
2. 执行查询
// 查询单行
func querySingleRow(db *sql.DB) {
var id int
var name string
err := db.QueryRow("SELECT id, name FROM users WHERE id = $1", 1).Scan(&id, &name)
if err != nil {
log.Fatal(err)
}
fmt.Printf("ID: %d, Name: %s\n", id, name)
}
// 查询多行
func queryMultipleRows(db *sql.DB) {
rows, err := db.Query("SELECT id, name FROM users WHERE age > $1", 18)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var id int
var name string
err = rows.Scan(&id, &name)
if err != nil {
log.Fatal(err)
}
fmt.Printf("ID: %d, Name: %s\n", id, name)
}
// 检查遍历过程中是否有错误
err = rows.Err()
if err != nil {
log.Fatal(err)
}
}
3. 执行插入、更新和删除
// 插入数据
func insertData(db *sql.DB) {
_, err := db.Exec("INSERT INTO users(name, age) VALUES($1, $2)", "Alice", 25)
if err != nil {
log.Fatal(err)
}
}
// 更新数据
func updateData(db *sql.DB) {
res, err := db.Exec("UPDATE users SET age = $1 WHERE name = $2", 26, "Alice")
if err != nil {
log.Fatal(err)
}
// 获取影响的行数
rowsAffected, err := res.RowsAffected()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Updated %d rows\n", rowsAffected)
}
// 删除数据
func deleteData(db *sql.DB) {
_, err := db.Exec("DELETE FROM users WHERE name = $1", "Alice")
if err != nil {
log.Fatal(err)
}
}
高级特性
1. 事务处理
func transferMoney(db *sql.DB, from, to int, amount float64) error {
tx, err := db.Begin()
if err != nil {
return err
}
// 确保事务在函数返回前被处理
defer func() {
if err != nil {
tx.Rollback()
return
}
err = tx.Commit()
}()
// 从转出账户扣款
_, err = tx.Exec("UPDATE accounts SET balance = balance - $1 WHERE id = $2", amount, from)
if err != nil {
return err
}
// 向转入账户加款
_, err = tx.Exec("UPDATE accounts SET balance = balance + $1 WHERE id = $2", amount, to)
if err != nil {
return err
}
return nil
}
2. 预处理语句
func preparedStatement(db *sql.DB) {
stmt, err := db.Prepare("SELECT name FROM users WHERE age > $1")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
rows, err := stmt.Query(18)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var name string
err = rows.Scan(&name)
if err != nil {
log.Fatal(err)
}
fmt.Println(name)
}
}
3. 处理 JSON 数据
PostgreSQL 支持 JSON 数据类型,pq 驱动可以很好地处理:
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func handleJSON(db *sql.DB) {
// 插入 JSON 数据
user := User{Name: "Bob", Age: 30}
_, err := db.Exec("INSERT INTO users(data) VALUES($1)", user)
if err != nil {
log.Fatal(err)
}
// 查询 JSON 数据
var data []byte
err = db.QueryRow("SELECT data FROM users WHERE id = $1", 1).Scan(&data)
if err != nil {
log.Fatal(err)
}
var retrievedUser User
err = json.Unmarshal(data, &retrievedUser)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Retrieved user: %+v\n", retrievedUser)
}
连接池配置
func setupConnectionPool(db *sql.DB) {
// 设置最大空闲连接数
db.SetMaxIdleConns(10)
// 设置最大打开连接数
db.SetMaxOpenConns(100)
// 设置连接最大存活时间
db.SetConnMaxLifetime(time.Hour)
}
注意事项
- 总是检查错误并处理
- 记得关闭连接和资源(rows, stmt, tx 等)
- 使用参数化查询防止 SQL 注入
- 连接字符串中的密码等敏感信息应该通过环境变量获取
pq 驱动提供了丰富的功能来与 PostgreSQL 交互,以上示例涵盖了大部分常见使用场景。对于更复杂的需求,可以参考 pq 的官方文档。