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")
}

状态

这个包目前处于维护模式,这意味着:

  1. 通常不接受新功能
  2. 接受社区提供的错误修复和版本兼容性更改
  3. 维护者通常不解决报告的问题
  4. 鼓励社区成员互相帮助解决报告的问题

对于需要新功能或可靠解决报告错误的用户,我们推荐使用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)
}

注意事项

  1. 总是检查错误并处理
  2. 记得关闭连接和资源(rows, stmt, tx 等)
  3. 使用参数化查询防止 SQL 注入
  4. 连接字符串中的密码等敏感信息应该通过环境变量获取

pq 驱动提供了丰富的功能来与 PostgreSQL 交互,以上示例涵盖了大部分常见使用场景。对于更复杂的需求,可以参考 pq 的官方文档。

回到顶部