Golang中如何理解db.Prepare的返回值

Golang中如何理解db.Prepare的返回值 在 database/sql/driver/driver.go 中,Conn 接口包含 Prepare 函数,该函数返回 Stmt。

type Conn interface {
	// Prepare 返回一个绑定到此连接的预处理语句
	Prepare(query string) (Stmt, error)

根据我的理解:

Prepare 函数的定义必须写在我们将要导入的驱动程序中。

驱动中的 Prepare 定义:

func (c *Conn) Prepare(query string) (driver.Stmt, error) {
	os, err := c.PrepareODBCStmt(query)
	if err != nil {
		return nil, err
	}
	return &Stmt{c: c, os: os, query: query}, nil
}

当我检查 driver.Stmt 的定义和返回的 Stmt 时,两者是不同的。 这是如何处理的?

谢谢


更多关于Golang中如何理解db.Prepare的返回值的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中如何理解db.Prepare的返回值的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言的database/sql/driver包中,Conn.Prepare方法返回一个driver.Stmt接口,但具体实现由数据库驱动提供。你观察到的现象是正确的:驱动中的Prepare方法返回的是自定义的Stmt结构体,但它必须实现driver.Stmt接口的所有方法。

driver.Stmt接口定义如下:

type Stmt interface {
    Close() error
    NumInput() int
    Exec(args []Value) (Result, error)
    Query(args []Value) (Rows, error)
}

在驱动实现中,返回的自定义Stmt结构体需要实现这些方法。例如:

// 驱动中的Stmt实现
type Stmt struct {
    c     *Conn
    os    *ODBCStmt  // 驱动特定的预处理语句句柄
    query string
}

func (s *Stmt) Close() error {
    return s.os.Close()
}

func (s *Stmt) NumInput() int {
    // 返回参数占位符的数量,-1表示未知
    return -1
}

func (s *Stmt) Exec(args []driver.Value) (driver.Result, error) {
    // 执行预处理语句的实现
    return s.c.execODBCStmt(s.os, args)
}

func (s *Stmt) Query(args []driver.Value) (driver.Rows, error) {
    // 查询预处理语句的实现
    return s.c.queryODBCStmt(s.os, args)
}

database/sql包调用驱动的Prepare方法时,它接收的是driver.Stmt接口类型。虽然实际返回的是*Stmt结构体指针,但只要该结构体实现了driver.Stmt接口的所有方法,Go语言的接口机制就会自动处理类型转换。

在使用层面,通过database/sql包的标准API:

stmt, err := db.Prepare("SELECT * FROM users WHERE id = ?")
if err != nil {
    log.Fatal(err)
}
defer stmt.Close()

rows, err := stmt.Query(1)
if err != nil {
    log.Fatal(err)
}
defer rows.Close()

这里db.Prepare返回的是*sql.Stmt,它内部封装了驱动的driver.Stmt实现。database/sql包在底层调用驱动的预处理语句方法,但对外提供统一的接口。

这种设计允许不同的数据库驱动提供各自的实现,同时保持用户代码的一致性。驱动返回的具体类型只要满足接口契约,就能被database/sql包正确使用。

回到顶部