golang简化pgx查询执行与结果扫描的插件库pig的使用
Golang简化pgx查询执行与结果扫描的插件库pig的使用
pig是一个简单的pgx包装器,用于执行和扫描查询结果。
特性
- 一体化工具
- 简单的事务管理:
- 可以设置
idle_in_transaction_session_timeout
本地选项 - 可以设置
statement_timeout
本地选项
- 可以设置
使用示例
执行查询
package main
import (
"context"
"log"
"github.com/alexeyco/pig"
"github.com/jackc/pgx/v4"
)
func main() {
// 创建pgx连接
conn, err := pgx.Connect(context.Background(), "")
if err != nil {
log.Fatalln(err)
}
// 创建pig实例
p := pig.New(conn)
// 执行删除操作
affectedRows, err := p.Query().Exec("DELETE FROM things WHERE id = $1", 123)
if err != nil {
log.Fatalln(err)
}
log.Println("affected", affectedRows, "rows")
}
获取单个实体
package main
import (
"context"
"log"
"github.com/alexeyco/pig"
"github.com/jackc/pgx/v4"
)
func main() {
// 创建pgx连接
conn, err := pgx.Connect(context.Background(), "")
if err != nil {
log.Fatalln(err)
}
// 创建pig实例
p := pig.New(conn)
// 查询单个值
var cnt int64
err = p.Query().Get(&cnt, "SELECT count(*) FROM things")
if err != nil {
log.Fatalln(err)
}
log.Println(cnt, "things found")
}
查询多个实体
package main
import (
"context"
"log"
"github.com/alexeyco/pig"
"github.com/jackc/pgx/v4"
)
// 定义模型结构
type Thing struct {
ID int64 `db:"id"`
Name string `db:"name"`
Quantity int64 `db:"quantity"`
}
func main() {
// 创建pgx连接
conn, err := pgx.Connect(context.Background(), "")
if err != nil {
log.Fatalln(err)
}
// 创建pig实例
p := pig.New(conn)
// 查询多个记录
var things []Thing
err = p.Query().Select(&things, "SELECT * FROM things")
if err != nil {
log.Fatalln(err)
}
log.Println(things)
}
事务处理
package main
import (
"context"
"log"
"time"
"github.com/alexeyco/pig"
"github.com/jackc/pgx/v4"
)
func main() {
// 创建pgx连接
conn, err := pgx.Connect(context.Background(), "")
if err != nil {
log.Fatalln(err)
}
// 创建pig实例
p := pig.New(conn)
// 执行事务操作
var affectedRows int64
err = p.Tx(pig.TransactionTimeout(time.Second)).
Exec(func(ex *pig.Ex) error {
affectedRows, err = p.Query().Exec("DELETE FROM things WHERE id = $1", 123)
if err != nil {
return err
}
return nil
})
if err != nil {
log.Fatalln(err)
}
log.Println("affected", affectedRows, "rows")
}
许可证
MIT License
Copyright (c) 2021 Alexey Popov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
更多关于golang简化pgx查询执行与结果扫描的插件库pig的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang简化pgx查询执行与结果扫描的插件库pig的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用pig库简化pgx查询与结果扫描
pig是一个轻量级的Golang库,专门用于简化pgx库的查询执行和结果扫描过程。它提供了更简洁的API来处理数据库操作,减少了样板代码。
安装
首先安装pig和pgx:
go get github.com/alexeyco/pig
go get github.com/jackc/pgx/v4
基本用法
1. 初始化连接
import (
"context"
"github.com/alexeyco/pig"
"github.com/jackc/pgx/v4/pgxpool"
)
func main() {
ctx := context.Background()
// 创建pgx连接池
pool, err := pgxpool.Connect(ctx, "postgres://user:password@localhost:5432/dbname")
if err != nil {
panic(err)
}
defer pool.Close()
// 创建pig查询器
q := pig.New(pool)
}
2. 查询单行数据
type User struct {
ID int64 `db:"id"`
Username string `db:"username"`
Email string `db:"email"`
}
func getUser(ctx context.Context, q *pig.Querier, id int64) (*User, error) {
var user User
err := q.QueryRow(ctx, &user,
"SELECT id, username, email FROM users WHERE id = $1", id)
if err != nil {
return nil, err
}
return &user, nil
}
3. 查询多行数据
func listUsers(ctx context.Context, q *pig.Querier) ([]User, error) {
var users []User
err := q.Query(ctx, &users,
"SELECT id, username, email FROM users ORDER BY id")
if err != nil {
return nil, err
}
return users, nil
}
4. 执行插入/更新/删除操作
func createUser(ctx context.Context, q *pig.Querier, username, email string) (int64, error) {
var id int64
err := q.QueryRow(ctx, &id,
"INSERT INTO users (username, email) VALUES ($1, $2) RETURNING id",
username, email)
if err != nil {
return 0, err
}
return id, nil
}
func updateUser(ctx context.Context, q *pig.Querier, id int64, email string) error {
_, err := q.Exec(ctx,
"UPDATE users SET email = $1 WHERE id = $2",
email, id)
return err
}
func deleteUser(ctx context.Context, q *pig.Querier, id int64) error {
_, err := q.Exec(ctx, "DELETE FROM users WHERE id = $1", id)
return err
}
高级特性
1. 事务处理
func transferMoney(ctx context.Context, q *pig.Querier, from, to int64, amount float64) error {
tx, err := q.Begin(ctx)
if err != nil {
return err
}
defer tx.Rollback(ctx) // 安全回滚
// 扣除发送方余额
_, err = tx.Exec(ctx,
"UPDATE accounts SET balance = balance - $1 WHERE id = $2",
amount, from)
if err != nil {
return err
}
// 增加接收方余额
_, err = tx.Exec(ctx,
"UPDATE accounts SET balance = balance + $1 WHERE id = $2",
amount, to)
if err != nil {
return err
}
return tx.Commit(ctx)
}
2. 自定义扫描逻辑
type CustomUser struct {
ID int64
FullName string
}
func (u *CustomUser) ScanRow(row pgx.Row) error {
return row.Scan(&u.ID, &u.FullName)
}
func getCustomUser(ctx context.Context, q *pig.Querier, id int64) (*CustomUser, error) {
var user CustomUser
err := q.QueryRow(ctx, &user,
"SELECT id, first_name || ' ' || last_name FROM users WHERE id = $1", id)
if err != nil {
return nil, err
}
return &user, nil
}
3. 批量插入
func batchInsertUsers(ctx context.Context, q *pig.Querier, users []User) error {
batch := &pgx.Batch{}
for _, user := range users {
batch.Queue(
"INSERT INTO users (username, email) VALUES ($1, $2)",
user.Username, user.Email,
)
}
return q.SendBatch(ctx, batch).Close()
}
性能考虑
- pig在内部使用了pgx的预处理语句缓存,重复查询会有更好的性能
- 对于大量数据的查询,考虑使用
QueryFunc
来流式处理结果 - 批量操作时使用pgx的Batch功能
pig库通过简化pgx的API,让数据库操作更加直观和易于维护,同时保持了pgx的高性能特性。它特别适合中小型项目,可以显著减少数据库访问层的样板代码。