golang SQLite3数据库驱动插件库go-sqlite3的使用
Golang SQLite3 数据库驱动插件库 go-sqlite3 的使用
简介
go-sqlite3 是一个符合内置 database/sql 接口的 SQLite3 驱动程序。
最新稳定版本是 v1.14 或更高版本,不是 v2。
安装
可以使用 go get
命令安装此包:
go get github.com/mattn/go-sqlite3
go-sqlite3 是一个 CGO 包。如果要使用 go-sqlite3 构建应用程序,需要安装 gcc。
重要提示:因为这是一个启用了 CGO 的包,所以需要设置环境变量 CGO_ENABLED=1
,并且在路径中要有 gcc
编译器。
基本使用示例
下面是一个完整的 go-sqlite3 使用示例:
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/mattn/go-sqlite3"
)
func main() {
// 打开数据库连接
db, err := sql.Open("sqlite3", "./example.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 创建表
sqlStmt := `
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER
);`
_, err = db.Exec(sqlStmt)
if err != nil {
log.Printf("%q: %s\n", err, sqlStmt)
return
}
// 插入数据
tx, err := db.Begin()
if err != nil {
log.Fatal(err)
}
stmt, err := tx.Prepare("INSERT INTO users(name, age) VALUES(?, ?)")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
_, err = stmt.Exec("Alice", 25)
if err != nil {
log.Fatal(err)
}
_, err = stmt.Exec("Bob", 30)
if err != nil {
log.Fatal(err)
}
tx.Commit()
// 查询数据
rows, err := db.Query("SELECT id, name, age FROM users")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var id int
var name string
var age int
err = rows.Scan(&id, &name, &age)
if err != nil {
log.Fatal(err)
}
fmt.Println(id, name, age)
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
}
连接字符串选项
创建新的 SQLite 数据库或连接到现有数据库时,可以在文件名后附加选项(也称为 DSN 字符串)。
选项附加在 SQLite 数据库文件名后,用 ?
分隔。多个选项可以用 &
连接。
示例:
// 使用共享缓存和内存模式
db, err := sql.Open("sqlite3", "file:test.db?cache=shared&mode=memory")
// 启用外键约束
db, err := sql.Open("sqlite3", "file:test.db?_foreign_keys=1")
// 设置繁忙超时为5000毫秒
db, err := sql.Open("sqlite3", "file:test.db?_busy_timeout=5000")
特性编译
可以通过构建标签启用或禁用 SQLite3 中的特定功能:
# 启用 ICU、JSON1、FTS5 和安全删除功能
go build -tags "icu json1 fts5 secure_delete"
用户认证
go-sqlite3 支持 SQLite 用户认证模块。要使用此功能,需要使用 sqlite_userauth
标签编译包。
创建受保护的数据库:
// 创建用户认证数据库,用户名为admin,密码为admin
db, err := sql.Open("sqlite3", "file:test.s3db?_auth&_auth_user=admin&_auth_pass=admin")
// 使用SHA1密码编码
db, err := sql.Open("sqlite3", "file:test.s3db?_auth&_auth_user=admin&_auth_pass=admin&_auth_crypt=sha1")
内存数据库
使用内存数据库的注意事项:
// 错误的用法 - 每个连接会创建新的内存数据库
db, err := sql.Open("sqlite3", ":memory:")
// 正确的用法 - 使用共享缓存
db, err := sql.Open("sqlite3", "file::memory:?cache=shared")
跨平台编译
在 Linux 上编译
go build -tags "linux"
在 macOS 上编译
# x86
go build -tags "darwin amd64"
# ARM
go build -tags "darwin arm64"
在 Windows 上编译
需要安装 Windows gcc 工具链(如 TDM-GCC)。
常见问题
-
数据库被锁定:
db, err := sql.Open("sqlite3", "file:locked.sqlite?cache=shared") db.SetMaxOpenConns(1)
-
内存数据库问题: 使用
"file::memory:?cache=shared"
而不是":memory:"
。 -
并发访问: 只读操作可以并发,但写入操作需要同步。
许可证
MIT 许可证:http://mattn.mit-license.org/2018
作者
Yasuhiro Matsumoto (a.k.a mattn)
G.J.R. Timmer
更多关于golang SQLite3数据库驱动插件库go-sqlite3的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang SQLite3数据库驱动插件库go-sqlite3的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Go-SQLite3 使用指南
go-sqlite3 是 Go 语言的一个 SQLite3 数据库驱动,它通过 cgo 封装了 SQLite3 的 C 语言 API。下面我将详细介绍如何使用这个库。
安装
首先需要安装 go-sqlite3:
go get github.com/mattn/go-sqlite3
注意:使用此库需要安装 GCC 编译环境,因为它使用了 cgo。
基本使用
1. 连接数据库
package main
import (
"database/sql"
"fmt"
"log"
_ "github.com/mattn/go-sqlite3"
)
func main() {
// 打开数据库连接
db, err := sql.Open("sqlite3", "./test.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 测试连接
err = db.Ping()
if err != nil {
log.Fatal(err)
}
fmt.Println("成功连接到SQLite数据库")
}
2. 创建表
func createTable(db *sql.DB) {
sqlStmt := `
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER,
email TEXT UNIQUE
);
`
_, err := db.Exec(sqlStmt)
if err != nil {
log.Printf("%q: %s\n", err, sqlStmt)
return
}
fmt.Println("表创建成功")
}
3. 插入数据
func insertUser(db *sql.DB, name string, age int, email string) {
stmt, err := db.Prepare("INSERT INTO users(name, age, email) VALUES(?, ?, ?)")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
res, err := stmt.Exec(name, age, email)
if err != nil {
log.Fatal(err)
}
id, err := res.LastInsertId()
if err != nil {
log.Fatal(err)
}
fmt.Printf("插入成功,ID: %d\n", id)
}
4. 查询数据
func queryUsers(db *sql.DB) {
rows, err := db.Query("SELECT id, name, age, email FROM users")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var id int
var name string
var age int
var email string
err = rows.Scan(&id, &name, &age, &email)
if err != nil {
log.Fatal(err)
}
fmt.Printf("ID: %d, Name: %s, Age: %d, Email: %s\n", id, name, age, email)
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
}
5. 更新数据
func updateUser(db *sql.DB, id int, newName string) {
stmt, err := db.Prepare("UPDATE users SET name = ? WHERE id = ?")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
res, err := stmt.Exec(newName, id)
if err != nil {
log.Fatal(err)
}
affected, err := res.RowsAffected()
if err != nil {
log.Fatal(err)
}
fmt.Printf("更新了 %d 行\n", affected)
}
6. 删除数据
func deleteUser(db *sql.DB, id int) {
stmt, err := db.Prepare("DELETE FROM users WHERE id = ?")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
res, err := stmt.Exec(id)
if err != nil {
log.Fatal(err)
}
affected, err := res.RowsAffected()
if err != nil {
log.Fatal(err)
}
fmt.Printf("删除了 %d 行\n", affected)
}
高级功能
1. 事务处理
func transactionExample(db *sql.DB) {
tx, err := db.Begin()
if err != nil {
log.Fatal(err)
}
// 在事务中执行多个操作
_, err = tx.Exec("INSERT INTO users(name, age, email) VALUES(?, ?, ?)", "Alice", 25, "alice@example.com")
if err != nil {
tx.Rollback()
log.Fatal(err)
}
_, err = tx.Exec("UPDATE users SET age = ? WHERE name = ?", 26, "Bob")
if err != nil {
tx.Rollback()
log.Fatal(err)
}
err = tx.Commit()
if err != nil {
log.Fatal(err)
}
fmt.Println("事务执行成功")
}
2. 使用连接池
func connectionPoolExample() {
db, err := sql.Open("sqlite3", "./test.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// 设置连接池参数
db.SetMaxOpenConns(10) // 最大打开连接数
db.SetMaxIdleConns(5) // 最大空闲连接数
db.SetConnMaxLifetime(time.Hour) // 连接最大存活时间
// 使用数据库...
}
3. 使用预编译语句
func preparedStatementExample(db *sql.DB) {
// 准备语句
stmt, err := db.Prepare("SELECT name FROM users WHERE age > ?")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
// 多次使用同一语句
rows, err := stmt.Query(20)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var name string
err = rows.Scan(&name)
if err != nil {
log.Fatal(err)
}
fmt.Println(name)
}
}
注意事项
-
并发访问:SQLite3 是文件数据库,多个写操作需要串行执行。go-sqlite3 内部已经处理了并发问题。
-
内存模式:可以使用
:memory:
作为数据库文件名创建内存数据库:db, err := sql.Open("sqlite3", ":memory:")
-
性能优化:对于大量插入操作,考虑使用事务可以显著提高性能。
-
CGO依赖:由于使用了 cgo,交叉编译时需要特别注意。
-
扩展支持:go-sqlite3 支持 SQLite3 的扩展,可以通过
Register
函数注册自定义扩展。
希望这个指南能帮助你开始使用 go-sqlite3。根据你的具体需求,可以进一步探索更高级的功能。