在一些场景中我们必要使用在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




还没有评论,来说两句吧...