From 65a711ad962f5fa4d0e643bc784fede8e240e1e4 Mon Sep 17 00:00:00 2001 From: asahi Date: Mon, 16 Jun 2025 12:49:28 +0800 Subject: [PATCH] =?UTF-8?q?doc:=20=E9=98=85=E8=AF=BBgolang=20sqlx=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Golang/go-sqlx.md | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/Golang/go-sqlx.md b/Golang/go-sqlx.md index 2f980a5..572a620 100644 --- a/Golang/go-sqlx.md +++ b/Golang/go-sqlx.md @@ -58,7 +58,7 @@ db, err = sqlx.Connect("sqlite3", ":memory:") // open and connect at the same time, panicing on error db = sqlx.MustConnect("sqlite3", ":memory:") ``` -## Query +## Quering handle Types中实现了和`database/sql`中同样的database方法: - `Exec(...) (sql.Result, error)`: 和`database/sql`中一致 - `Query(...) (*sql.Rows, error)`:和`database/sql`中一致 @@ -76,7 +76,9 @@ handle Types中实现了和`database/sql`中同样的database方法: ### Exec `Exec`和`MustExec`方法会从connection pool中获取连接并且执行提供的sql方法。 -> 并且,在result返回之前,连接将会被归还到连接池。(因为Exec是非事务的,故而连接无需等待result返回,可以直接被其他协程使用)。 +> 并且,在Exec向调用方返回`sql.Result`对象之前,连接将会被归还给连接池。 +> +> `此时,server已经向client发送了query text的执行结果,在根据返回结果构建sql.Result对象之前,会将来凝结返回给连接池。` ```go schema := `CREATE TABLE place ( @@ -122,6 +124,32 @@ db.Query("SELECT * FROM ?", "mytable") // also doesn't work db.Query("SELECT ?, ? FROM people", "name", "location") ``` - +### Query +`database/sql`主要通过`Query`方法来执行查询语句并获取row results。`Query`方法会返回一个`sql.Rows`对象和一个error, +```go +// fetch all places from the db +rows, err := db.Query("SELECT country, city, telcode FROM place") + +// iterate over each row +for rows.Next() { + var country string + // note that city can be NULL, so we use the NullString type + var city sql.NullString + var telcode int + err = rows.Scan(&country, &city, &telcode) +} +// check the error from rows +err = rows.Err() +``` +在使用Rows时,应当将其看作是database cursor,而非是结果反序列化之后构成的列表。尽管驱动对结果集的缓存行为各不相同,但是通过`Next`方法对`Rows`中的结果进行迭代仍然可以在result set较大的场景下节省内存的使用,因为`Next`同时只会对一行结果进行扫描。 + +`Scan`方法会使用反射将column返回的结果类型映射为go类型(例如string, []byte等)。 + +> 在使用`Rows`时,如果并不迭代完整个结果集,请确保调用`rows.Close()`方法将连接返回到连接池中。 + +### Exec和Query在归还连接池上的差异 +Exec操作和Query操作在归还连接到连接池的时机有所不同: +- `Exec`: `Exec`方法在`server返回执行结果给client之后`,`client根据返回结果构建并返回sql.Result之前`,将会将连接返回给连接池 +- `Query`: `Query`方法和`Exec`方法不同,其返回信息中包含结果集,必须等待结果集`迭代完成`或`手动调用rows.Close`方法之后,才会归还连接给连接池