为了账号安全,请及时绑定邮箱和手机立即绑定

pgx lib中的命名准备语句,它是如何工作的?

pgx lib中的命名准备语句,它是如何工作的?

Go
holdtom 2023-06-05 17:57:17
介绍数据库/sql在 Go 标准 sql 库中,该*Stmt类型具有如下定义的方法:func (s *Stmt) Exec(args ...interface{}) (Result, error) func (s *Stmt) Query(args ...interface{}) (*Rows, error)新的(未命名的)语句由以下人员准备:func (db *DB) Prepare(query string) (*Stmt, error)连接池是抽象的,不能直接访问在单个连接上准备事务如果连接在语句执行时不可用,它将在新连接上重新准备。pgx该PreparedStatement类型没有定义任何方法。一个新的命名准备语句由以下人员准备:func (p *ConnPool) Prepare(name, sql string) (*PreparedStatement, error)操作直接在连接池上事务在池的所有连接上准备好没有明确的方法如何执行准备好的语句Prepare 是幂等的;也就是说,使用相同的名称和 sql 参数多次调用 Prepare 是安全的。这允许Prepare 和 Query/Exec/PrepareEx 的代码路径,而不用担心语句是否已经准备好。小例子package mainimport (    "github.com/jackc/pgx")func main() {    conf := pgx.ConnPoolConfig{        ConnConfig: pgx.ConnConfig{            Host:     "/run/postgresql",            User:     "postgres",            Database: "test",        },        MaxConnections: 5,    }    db, err := pgx.NewConnPool(conf)    if err != nil {        panic(err)    }    _, err = db.Prepare("my-query", "select $1")    if err != nil {        panic(err)    }    // What to do with the prepared statement?}问题)该name参数给我的印象是它可以通过调用它来执行name,但是如何呢?该文档给人的印象是Query/Exec方法以某种方式利用了准备好的语句。但是,这些方法不接受参数name。它如何匹配它们?据推测,匹配是由查询内容完成的。那么命名语句的意义何在?可能的答案这是我得到的结果:没有按名称引用查询的方法(假设)匹配是在查询主体上完成的conn.ExecEx()。如果还没有准备好,将完成:ps, ok := c.preparedStatements[sql]            if !ok {                var err error                ps, err = c.prepareEx("", sql, nil)                if err != nil {                    return "", err                }            }PosgreSQL 本身需要它来做某事(假设)。
查看完整描述

1 回答

?
繁星coding

TA贡献1797条经验 获得超4个赞

它在这里有双重功能。如果sql变量与映射中的键不匹配c.preparedStatements[sql],则准备好包含在 中的查询sql并将新*PreparedStatement结构指定给ps. 如果它确实匹配了一个键,ps变量将指向地图的一个条目。


如此有效,您可以执行以下操作:


package main


import (

    "fmt"


    "github.com/jackc/pgx"

)


func main() {

    conf := pgx.ConnPoolConfig{

        ConnConfig: pgx.ConnConfig{

            Host:     "/run/postgresql",

            User:     "postgres",

            Database: "test",

        },

        MaxConnections: 5,

    }

    db, err := pgx.NewConnPool(conf)

    if err != nil {

        panic(err)

    }

    if _, err := db.Prepare("my-query", "select $1::int"); err != nil {

        panic(err)

    }

    row := db.QueryRow("my-query", 10)

    var i int

    if err := row.Scan(&i); err != nil {

        panic(err)

    }

    fmt.Println(i)

}


查看完整回答
反对 回复 2023-06-05
  • 1 回答
  • 0 关注
  • 80 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信