golang轻松操作rqlite数据库API的客户端插件go-rqlite的使用
Golang轻松操作rqlite数据库API的客户端插件go-rqlite使用指南
概述
gorqlite是一个用于rqlite的Go客户端,提供了易于使用的抽象层来操作rqlite API。它提供了专门为rqlite设计的惯用API,以及一个database/sql驱动。
主要特性
- 抽象了rqlite HTTP API交互 - POST请求、JSON处理等
- 提供类似database/sql的语义,如
Open()
、Query()
、QueryOne()
、Next()
/Scan()
/Map()
、Write()
和WriteOne()
等 - 支持rqlite特有的操作:
Leader()
和Peers()
检查集群、SetConsistencyLevel()
更改一致性级别 - 支持调试跟踪功能
Trace(io.Writer)
/Trace(nil)
- 无外部依赖,仅使用标准库函数
安装
go get github.com/rqlite/gorqlite
使用示例
基本连接
// 连接到localhost:4001无认证
conn, err := gorqlite.Open("http://")
// 使用HTTPS
conn, err := gorqlite.Open("https://")
// 明确指定地址
conn, err := gorqlite.Open("https://localhost:4001/")
// 带认证的连接
conn, err := gorqlite.Open("https://mary:secret2@localhost:4001/")
// 设置一致性级别
conn, err := gorqlite.Open("https://server2.example.com:4001/?level=weak")
// 设置超时
conn, err := gorqlite.Open("https://localhost:2265/?level=strong&timeout=30")
// 禁用集群发现
conn, err := gorqlite.Open("https://localhost:2265/?disableClusterDiscovery=true")
自定义HTTP客户端
// 创建跳过证书验证的TLS传输
tn := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
// 创建HTTP客户端并传递给库
client := &http.Client{Transport: tn}
conn, err := gorqlite.OpenWithClient("https://localhost:4001/", client)
执行写入操作
// 模拟database/sql Prepare()
statements := make([]string, 0)
pattern := "INSERT INTO secret_agents(id, hero_name, abbrev) VALUES (%d, '%s', '%3s')"
statements = append(statements, fmt.Sprintf(pattern, 125718, "Speed Gibson", "Speed"))
statements = append(statements, fmt.Sprintf(pattern, 209166, "Clint Barlow", "Clint"))
statements = append(statements, fmt.Sprintf(pattern, 44107, "Barney Dunlap", "Barney"))
results, err := conn.Write(statements)
// 处理结果
for n, v := range results {
fmt.Printf("结果%d影响了%d行\n", n, v.RowsAffected)
if v.Err != nil {
fmt.Printf("错误: %s\n", v.Err.Error())
}
}
// 单条写入并获取最后插入ID
res, err := conn.WriteOne("INSERT INTO foo (name) values ('bar')")
fmt.Printf("最后插入ID: %d\n", res.LastInsertID)
执行查询操作
var id int64
var name string
// 查询单条语句
rows, err := conn.QueryOne("select id, name from secret_agents where id > 500")
fmt.Printf("查询返回%d行\n", rows.NumRows)
// 遍历结果
for rows.Next() {
err := rows.Scan(&id, &name)
fmt.Printf("这是第%d行\n", rows.RowNumber)
fmt.Printf("总共有%d行\n", rows.NumRows)
}
// 使用Map()获取结果
for rows.Next() {
m, err := rows.Map()
// m现在是map[列名]interface{}
id := m["id"].(float64) // JSON数字类型
name := m["name"].(string)
}
参数化查询
// 参数化写入
wr, err := conn.WriteParameterized(
[]gorqlite.ParameterizedStatement{
{
Query: "INSERT INTO secret_agents(id, name, secret) VALUES(?, ?, ?)",
Arguments: []interface{}{7, "James Bond", "not-a-secret"},
},
},
)
// 参数化查询
qr, err := conn.QueryParameterized(
[]gorqlite.ParameterizedStatement{
{
Query: "SELECT id, name from secret_agents where id > ?",
Arguments: []interface{}{3},
},
},
)
集群信息
// 获取当前Leader
leader, err := conn.Leader()
fmt.Println("当前Leader:", leader)
// 获取所有Peer
peers, err := conn.Peers()
for n, p := range peers {
fmt.Printf("集群Peer %d: %s\n", n, p)
}
调试跟踪
// 开启调试跟踪到文件
f, err := os.OpenFile("/tmp/deep_insights.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
gorqlite.TraceOn(f)
// 改为跟踪到标准错误
gorqlite.TraceOn(os.Stderr)
// 关闭跟踪
gorqlite.TraceOff()
database/sql驱动使用
package main
import (
"database/sql"
_ "github.com/rqlite/gorqlite/stdlib"
)
func main() {
db, err := sql.Open("rqlite", "http://")
if err != nil {
panic(err)
}
_, err = db.Exec("CREATE TABLE users (id INTEGER, name TEXT)")
if err != nil {
panic(err)
}
}
重要注意事项
- 如果使用访问控制,连接用户需要_status_权限
- rqlite不支持迭代获取,查询会将所有结果立即放入内存
- 在标准database/sql驱动中有一些限制:
- 事务必须作为单个批处理提交
- 不支持回滚
- Prepare()是空操作
完整示例
package main
import (
"fmt"
"github.com/rqlite/gorqlite"
"os"
)
func main() {
// 1. 连接到rqlite
conn, err := gorqlite.Open("http://localhost:4001")
if err != nil {
fmt.Printf("连接错误: %v\n", err)
return
}
// 2. 创建表
_, err = conn.WriteOne("CREATE TABLE IF NOT EXISTS users (id INTEGER, name TEXT)")
if err != nil {
fmt.Printf("创建表错误: %v\n", err)
return
}
// 3. 插入数据
res, err := conn.WriteOne("INSERT INTO users (id, name) VALUES (1, 'Alice')")
if err != nil {
fmt.Printf("插入错误: %v\n", err)
return
}
fmt.Printf("插入影响行数: %d\n", res.RowsAffected)
// 4. 查询数据
rows, err := conn.QueryOne("SELECT id, name FROM users")
if err != nil {
fmt.Printf("查询错误: %v\n", err)
return
}
for rows.Next() {
var id int64
var name string
err = rows.Scan(&id, &name)
if err != nil {
fmt.Printf("扫描错误: %v\n", err)
continue
}
fmt.Printf("ID: %d, Name: %s\n", id, name)
}
// 5. 获取集群信息
leader, err := conn.Leader()
if err != nil {
fmt.Printf("获取Leader错误: %v\n", err)
} else {
fmt.Printf("当前Leader: %s\n", leader)
}
peers, err := conn.Peers()
if err != nil {
fmt.Printf("获取Peers错误: %v\n", err)
} else {
fmt.Println("集群Peers:")
for i, peer := range peers {
fmt.Printf(" %d: %s\n", i, peer)
}
}
}
这个客户端库已被多个组织在生产环境中使用,包括Replicated。它提供了简单易用的API来操作rqlite数据库,适合需要高可用性SQLite解决方案的场景。
更多关于golang轻松操作rqlite数据库API的客户端插件go-rqlite的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang轻松操作rqlite数据库API的客户端插件go-rqlite的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用go-rqlite轻松操作rqlite数据库
rqlite是一个轻量级的分布式关系数据库,基于SQLite构建,提供了HTTP API接口。go-rqlite是rqlite的官方Go客户端库,让开发者可以方便地在Go应用中操作rqlite数据库。
安装go-rqlite
go get github.com/rqlite/go-rqlite
基本使用方法
1. 连接到rqlite服务器
package main
import (
"fmt"
"log"
"github.com/rqlite/go-rqlite"
)
func main() {
// 连接到本地rqlite服务器
conn, err := rqlite.NewConnection("http://localhost:4001")
if err != nil {
log.Fatalf("连接失败: %v", err)
}
defer conn.Close()
// 检查连接状态
if err := conn.Ping(); err != nil {
log.Fatalf("ping失败: %v", err)
}
fmt.Println("成功连接到rqlite服务器")
}
2. 执行SQL语句
// 创建表
func createTable(conn *rqlite.Connection) error {
_, err := conn.Execute("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)")
return err
}
// 插入数据
func insertData(conn *rqlite.Connection) error {
_, err := conn.Execute("INSERT INTO users(name, age) VALUES('Alice', 25), ('Bob', 30)")
return err
}
3. 查询数据
func queryData(conn *rqlite.Connection) error {
rows, err := conn.Query("SELECT * FROM users")
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var id, age int
var name string
if err := rows.Scan(&id, &name, &age); err != nil {
return err
}
fmt.Printf("ID: %d, Name: %s, Age: %d\n", id, name, age)
}
return rows.Err()
}
高级功能
1. 事务处理
func transactionExample(conn *rqlite.Connection) error {
tx, err := conn.Begin()
if err != nil {
return err
}
// 执行事务中的操作
if _, err := tx.Execute("INSERT INTO users(name, age) VALUES('Charlie', 28)"); err != nil {
tx.Rollback()
return err
}
if _, err := tx.Execute("UPDATE users SET age = 26 WHERE name = 'Alice'"); err != nil {
tx.Rollback()
return err
}
// 提交事务
return tx.Commit()
}
2. 批量操作
func batchExample(conn *rqlite.Connection) error {
statements := []string{
"INSERT INTO users(name, age) VALUES('David', 35)",
"INSERT INTO users(name, age) VALUES('Eve', 22)",
"DELETE FROM users WHERE age > 30",
}
_, err := conn.ExecuteBatch(statements)
return err
}
3. 参数化查询
func parameterizedQuery(conn *rqlite.Connection) error {
rows, err := conn.QueryParameterized(
"SELECT * FROM users WHERE age > ?",
[]interface{}{25},
)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var id, age int
var name string
if err := rows.Scan(&id, &name, &age); err != nil {
return err
}
fmt.Printf("ID: %d, Name: %s, Age: %d\n", id, name, age)
}
return rows.Err()
}
完整示例
package main
import (
"fmt"
"log"
"github.com/rqlite/go-rqlite"
)
func main() {
// 1. 连接
conn, err := rqlite.NewConnection("http://localhost:4001")
if err != nil {
log.Fatal(err)
}
defer conn.Close()
// 2. 创建表
if err := createTable(conn); err != nil {
log.Fatal(err)
}
// 3. 插入数据
if err := insertData(conn); err != nil {
log.Fatal(err)
}
// 4. 查询数据
fmt.Println("初始数据:")
if err := queryData(conn); err != nil {
log.Fatal(err)
}
// 5. 事务操作
if err := transactionExample(conn); err != nil {
log.Fatal(err)
}
// 6. 再次查询
fmt.Println("\n事务后的数据:")
if err := queryData(conn); err != nil {
log.Fatal(err)
}
// 7. 参数化查询
fmt.Println("\n年龄大于25的用户:")
if err := parameterizedQuery(conn); err != nil {
log.Fatal(err)
}
}
// 其他函数定义同上...
注意事项
- rqlite默认使用强一致性模式,所有写操作都会等待leader节点确认
- 对于高并发场景,可以考虑使用连接池
- 生产环境建议配置多个节点实现高可用
- 大表查询可能会影响性能,建议添加适当的索引
go-rqlite提供了简单直观的API,让Go开发者可以轻松地与rqlite数据库交互,同时支持事务、批量操作等高级功能,非常适合需要SQLite功能但又要分布式特性的应用场景。