Sqlx是一个第三方库,它为database/sql
包提供了一系列非常有用的扩展功能。因为Sqlx和database/sql
包使用的是相同的接口,所以Sqlx能够很好地兼容使用database/sql
包的程序,除此之外,Sqlx还提供了以下这些额外的功能:
- 通过结构标签(struct tag)将数据库记录(即行)封装为结构、映射或者切片;
- 为预处理语句提供具名参数支持。
代码清单6-17展示了如何使用Sqlx及其提供的StructScan
方法来对论坛程序进行简化。另外别忘了,在使用Sqlx库之前,需要先通过执行以下命令来获取这个库:
go get "github.com/jmoiron/sqlx"
代码清单6-17 使用Sqlx重新实现论坛程序
package main
import (
"fmt"
"github.com/jmoiron/sqlx"
_ "github.com/lib/pq"
)
type Post struct {
Id int
Content string
AuthorName string `db: author`
}
var Db *sqlx.DB
func init() {
var err error
Db, err = sqlx.Open("postgres", "user=gwp dbname=gwp password=gwp sslmode=disable")
if err != nil {
panic(err)
}
}
func GetPost(id int) (post Post, err error) {
post = Post{}
err = Db.QueryRowx("select id, content, author from posts where id = $1", id)
.StructScan(&post)
if err != nil {
return
}
return
}
func (post *Post) Create() (err error) {
err = Db.QueryRow("insert into posts (content, author) values ($1, $2) returning id",
post.Content, post.AuthorName).Scan(&post.Id)
return
}
func main() {
post := Post{Content: "Hello World!", AuthorName: "Sau Sheong"} post.Create()
fmt.Println(post) //①{1 Hello World! Sau Sheong}}
}
代码清单中的加粗代码展示了使用Sqlx与使用database/sql
之间的区别,而其余的则是一些我们之前已经看到过的代码。首先,程序现在不再导入database/sql
包,而是导入github.com/jmoiron/sqlx
包。在默认情况下,StructScan
会根据结构字段名的英文小写体,将结构中的字段映射至表中的列。为了演示如何将指定的表列映射至指定的结构字段,代码清单6-17将原来的Author
字段修改成了AuthorName
字段,然后通过结构标签来指示Sqlx应该从author
列里面获取AuthorName
字段的数据。本书将在第7章对结构标签做进一步的说明。
程序现在也会使用sqlx.DB
结构来代替之前的sql.DB
结构,这两种结构非常相似,只不过sqlx.DB
包含了诸如Queryx
以及QueryRowx
等额外的方法。
修改之后的GetPost
函数也使用QueryRowx
代替了之前的QueryRow
。QueryRowx
在执行之后将返回Rowx
结构,这种结构拥有StructScan
方法,该方法可以将列自动地映射到相应的字段里面。另一方面,对于Create
方法,我们还是跟之前一样,使用QueryRow
方法进行查询。
除了这里提到的特性之外,Sqlx还拥有其他一些有趣的特性,感兴趣的读者可以通过访问Sqlx的GitHub页面来了解:https://github.com/jmoiron/sqlx。
Sqlx是一个有趣并且有用的database/sql
扩展,但它支持的特性并不多。与此相反,我们接下来要学习的Gorm
库不仅把database/sql
包隐藏了起来,它还提供了一个完整且强大的ORM
机制来代替database/sql
包。