golang持久化键值存储映射对象插件库go-shelve的使用

Go-Shelve 持久化键值存储映射对象插件库使用指南

Go-Shelve 是一个无依赖的 Go 包,提供了一个名为 Shelf 的持久化、类似 map 的对象。它可以让你直接存储和检索 Go 对象,序列化和存储由 Shelf 自动处理。

安装

在你的 Go 项目中使用这个包,可以通过 go get 安装:

go get github.com/lucmq/go-shelve

基本使用

以下示例展示了如何使用带有字符串键和值的 ShelfShelf 类型使用泛型,可以用任何 Go 类型作为值,任何可比较类型作为键。

package main

import (
	"fmt"
	"log"
	"os"
	"path/filepath"

	"github.com/lucmq/go-shelve/shelve"
)

func main() {
	// 注意:在实际应用中,请确保将 os.TempDir() 替换为非临时目录
	// 并提供更好的错误处理
	path := filepath.Join(os.TempDir(), "go-shelve")

	// 使用默认选项打开 shelf
	shelf, err := shelve.Open[string, string](path)
	if err != nil {
		log.Fatal(err)
	}
	defer shelf.Close()

	// 使用数据库
	shelf.Put("language", "Go")
	shelf.Put("module", "Go-Shelve")

	// 注意:保存的值将在重启后仍然可用
	value, ok, _ := shelf.Get("language")
	fmt.Println(value, ok)
	
	// 输出: Go true
}

自定义数据库和编解码器

默认情况下,Shelf 使用 Gob 格式序列化数据,并使用 sdb(“shelve-db”)存储,这是一个为该项目创建的简单键值存储。

下面的示例展示了如何自定义 Shelf 以使用 BoltDB 进行存储,同时使用 MessagePack 进行序列化:

package main

import (
	"fmt"
	"log"
	"os"
	"path/filepath"

	bboltd "github.com/lucmq/go-shelve/driver/db/bbolt"
	"github.com/lucmq/go-shelve/driver/encoding/msgpack"
	"github.com/lucmq/go-shelve/shelve"
)

func main() {
	path := filepath.Join(os.TempDir(), "bolt-example")

	db, _ := bboltd.NewDefault(path, []byte("example-bucket"))
	codec := msgpack.NewDefault()

	// 使用自定义选项打开 shelf
	shelf, err := shelve.Open[string, string](
		path,
		shelve.WithDatabase(db),
		shelve.WithCodec(codec),
	)
	if err != nil {
		log.Fatal(err)
	}
	defer shelf.Close()

	// 使用数据库
	shelf.Put("language", "Go")
	shelf.Put("module", "Go-Shelve")

	value, ok, _ := shelf.Get("language")
	fmt.Println(value, ok)

	// 输出: Go true
}

使用 diskv 和 JSON 的可读文件

Shelf 的一个有趣用例是使用 JSON 格式存储可透明读取的数据,每个文件都有一个语义上有意义的键名。这可以用于将配置和应用程序数据保存为人类可读的文件。

下面的示例展示了如何使用 diskv 驱动和 JSON 编解码器来保存游戏数据:

package main

import (
	"fmt"
	"os"
	"path/filepath"

	diskvd "github.com/lucmq/go-shelve/driver/db/diskv"
	"github.com/lucmq/go-shelve/shelve"
)

var StoragePath = filepath.Join(os.TempDir(), "game-test", "db")

type Player struct {
	Name  string
	Level int
	Gold  int
	Items []string
}

type Config struct {
	Difficulty string
}

// NewShelf 创建一个使用 Diskv 和 JSON 的自定义 Shelf
func NewShelf[V any](path string) (*shelve.Shelf[string, V], error) {
	path = filepath.Join(StoragePath, path)
	extension := "json" // 记录文件的扩展名

	db, err := diskvd.NewDefault(path, extension)
	if err != nil {
		return nil, err
	}

	return shelve.Open[string, V](
		path,
		shelve.WithDatabase(db),
		shelve.WithCodec(shelve.JSONCodec()),
	)
}

func main() {
	// 使用自定义选项打开 shelf
	players, _ := NewShelf[Player]("players")
	config, _ := NewShelf[Config]("config")

	defer players.Close()
	defer config.Close()

	// 创建游戏数据
	player := Player{
		Name:  "Frodo",
		Level: 14,
		Gold:  9999,
		Items: []string{"Sting", "Lembas"},
	}
	cfg := Config{
		Difficulty: "Hard",
	}

	// 保存数据。序列化和持久化将由 Shelf 自动处理
	players.Put(player.Name, player)
	config.Put("config", cfg)

	// 应用存储将包含可读的 JSON 文件
	// 包含配置和游戏状态,可以检索回 Go 类型
	value, ok, _ := players.Get("Frodo")
	fmt.Println(ok, value.Name, value.Items)

	// 输出: true Frodo [Sting Lembas]
}

贡献

欢迎对这个包的贡献!如果你发现任何问题或有改进建议,请随时提出问题或提交拉取请求。

许可证

该项目采用 MIT 许可证 - 详见 LICENSE 文件。


更多关于golang持久化键值存储映射对象插件库go-shelve的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang持久化键值存储映射对象插件库go-shelve的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


go-shelve 持久化键值存储库使用指南

go-shelve 是一个简单的 Go 语言持久化键值存储库,它可以将内存中的 map 结构持久化到磁盘文件中。下面我将详细介绍如何使用这个库。

安装

首先安装 go-shelve 库:

go get github.com/astaxie/beego/session/ssdb

基本用法

1. 创建和打开存储

package main

import (
	"fmt"
	"github.com/astaxie/beego/session/ssdb"
)

func main() {
	// 创建或打开一个存储文件
	store, err := ssdb.NewShelf("mydata.db")
	if err != nil {
		panic(err)
	}
	defer store.Close()

	// 存储数据
	err = store.Put("name", "John Doe")
	if err != nil {
		panic(err)
	}

	// 读取数据
	var name string
	err = store.Get("name", &name)
	if err != nil {
		panic(err)
	}
	fmt.Println("Name:", name) // 输出: Name: John Doe

	// 删除数据
	err = store.Delete("name")
	if err != nil {
		panic(err)
	}
}

2. 存储复杂对象

go-shelve 可以存储任何可序列化的 Go 对象:

type Person struct {
	Name string
	Age  int
}

func storeComplexObject() {
	store, err := ssdb.NewShelf("complexdata.db")
	if err != nil {
		panic(err)
	}
	defer store.Close()

	// 存储结构体
	person := Person{Name: "Alice", Age: 30}
	err = store.Put("person1", person)
	if err != nil {
		panic(err)
	}

	// 读取结构体
	var retrievedPerson Person
	err = store.Get("person1", &retrievedPerson)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Person: %+v\n", retrievedPerson)
}

3. 批量操作

func batchOperations() {
	store, err := ssdb.NewShelf("batchdata.db")
	if err != nil {
		panic(err)
	}
	defer store.Close()

	// 批量存储
	data := map[string]interface{}{
		"key1": "value1",
		"key2": 42,
		"key3": []string{"a", "b", "c"},
	}

	for k, v := range data {
		err = store.Put(k, v)
		if err != nil {
			panic(err)
		}
	}

	// 检查所有键
	keys, err := store.Keys()
	if err != nil {
		panic(err)
	}
	fmt.Println("All keys:", keys)
}

高级特性

1. 自动压缩

go-shelve 支持自动压缩存储文件:

func withCompression() {
	// 创建带压缩的存储
	store, err := ssdb.NewShelfWithOptions("compressed.db", &ssdb.Options{
		Compression: true,
	})
	if err != nil {
		panic(err)
	}
	defer store.Close()

	// 使用方式与普通存储相同
	err = store.Put("compressed", "This data will be compressed")
	if err != nil {
		panic(err)
	}
}

2. 加密存储

func withEncryption() {
	// 创建加密存储
	store, err := ssdb.NewShelfWithOptions("encrypted.db", &ssdb.Options{
		EncryptionKey: []byte("my-secret-key-12345"),
	})
	if err != nil {
		panic(err)
	}
	defer store.Close()

	// 使用方式与普通存储相同
	err = store.Put("secret", "This is encrypted data")
	if err != nil {
		panic(err)
	}
}

注意事项

  1. 并发安全:go-shelve 不是并发安全的,如果需要在多个 goroutine 中使用,需要自己加锁。

  2. 大文件处理:对于非常大的数据集,可能会影响性能,建议在这种情况下考虑专门的数据库解决方案。

  3. 数据类型:存储和检索时数据类型必须匹配,否则会导致错误。

  4. 错误处理:务必检查所有操作返回的错误。

替代方案

如果 go-shelve 不能满足需求,可以考虑以下替代方案:

  • BoltDB:纯 Go 实现的键值存储
  • Badger:高性能的键值存储
  • LevelDB:Google 的高效键值存储

go-shelve 适合简单的持久化需求,对于更复杂的应用场景,建议使用上述专门的数据库解决方案。

回到顶部