在一些场景中我们必要使用在sqlite查询中好用的函数,
这样更加方便,更加好用,嘿嘿
比如下面将给出的例子中我们获取一个字符串的MD5值是很常见的。
如果返回结果要加上这个计算好的值,需要在结果集内一一处理。
下面我们就开始使用。首先要用到一个golang的第三方包:
go get -u github.com/mattn/go-sqlite3 # sqlite3 "github.com/mattn/go-sqlite3"
golang 的标准库 数据库 database/sql
有一个 sql.Register
下面就看看注册函数的完整使用例子
sql.Register("sqlite3_extended", &sqlite3.SQLiteDriver{ ConnectHook: func(sc *sqlite3.SQLiteConn) error { return sc.RegisterFunc("md5", MD5, true) }, })
其中这里用到的 go-sqlite3 这个库中的 ConnectHook 连接钩子
然后我们家可以使用了 标准库sql查询的例子:
db, err := sql.Open("sqlite3_extended", ":memory:") if err != nil { fmt.Println(err.Error()) } defer db.Close() err = db.QueryRow("SELECT md5('hello world')").Scan(&result) if err != nil { fmt.Println(err.Error()) }
这里我们主要看看 ConnectHook 这个函数的相关说明:
这个绑定回调你的函数支持的返回类型 SQLite 数据 → Go 类型(只有这些,不能用 time.Time、struct 等):
INTEGER → int64
FLOAT → float64
TEXT → string
BLOB → []byte
NULL → nil(以 interface{} 形式传进来)
接收 interface{}:func f(args ...interface{}) interface{}
sqlite3.SQLiteConn.RegisterFunc 说明
注册函数名
函数体
pure
pure = true SQLite 认为“相同输入一定相同输出”,可缓存结果,查询更激进优化。在 CHECK 约束、部分索引里必须用纯函数。
pure = false 每次调用都重新计算(如含随机数、读文件、时间等)。下面看一个完整的实例 使用了标准库和GORM的例子:
package main /* 这个例子展示了如何在 SQLite 中注册并使用自定义的 MD5 函数。 我们使用:github.com/mattn/go-sqlite3 通过在连接钩子中注册自定义函数,我们可以在 SQL 查询中调用该函数。 注意:确保你已经安装了所需的包: go get github.com/mattn/go-sqlite3 go get gorm.io/gorm go get gorm.io/driver/sqlite go get github.com/glebarez/sqlite author: icy blog: https://zelig.cn */ import ( "crypto/md5" "database/sql" "encoding/hex" "fmt" sdb "github.com/glebarez/sqlite" sqlite3 "github.com/mattn/go-sqlite3" "gorm.io/gorm" ) func main() { // 注册自定义的 MD5 函数 MD5 := func(str string) string { _md5 := md5.New() _md5.Write([]byte(str)) return hex.EncodeToString(_md5.Sum([]byte(""))) } sql.Register("sqlite3_extended", // 注册自定义驱动名 &sqlite3.SQLiteDriver{ /// 这里是连接钩子,用于在每次数据库连接时注册自定义函数 ConnectHook: func(sc *sqlite3.SQLiteConn) error { return sc.RegisterFunc("md5", MD5, true) }, }) var result string /* // 使用标准库打开数据库连接 db, err := sql.Open("sqlite3_extended", ":memory:") if err != nil { fmt.Println(err.Error()) } defer db.Close() err = db.QueryRow("SELECT md5('hello world')").Scan(&result) if err != nil { fmt.Println(err.Error()) } */ // 使用 GORM 打开数据库连接 设置驱动名和 DSN - 主要是驱动名要和上面注册的保持一致 db, err := gorm.Open(sdb.Dialector{DriverName: "sqlite3_extended", DSN: "test.db"}, &gorm.Config{}) if err != nil { fmt.Println(err.Error()) } db.Raw("select md5('hello world')").Scan(&result) fmt.Println(result) }
运行返回:
好了你可以 开发一个包 把一些常用的注册到函数 写到一起了。
如果你不想开发。还有更懒的做法:
sql.Register("sqlite3_ext", &sqlite3.SQLiteDriver{ Extensions: []string{ "...", }, })
使用扩展包
扩展包可以 从 https://sqlpkg.org/all/ 获取。linux/MacOS/Windows 系统下载对应的即可
也可以下载 sqlpkg 工具 使用命令
sqlpkg install asg017/lines
还没有评论,来说两句吧...