logo
0
0
WeChat Login
🐛fix: 修复与重构,突出缓存生命周期和并发安全的改进,修补了删除链路、缓存后台协程和并发查询的设计缺陷,并将底层存储切换到 bbolt 以支持竞态检测。

kv2doc

Go Report Card GoDoc Go Version License

kv2doc 是一个高性能的嵌入式文档数据库,基于 Go 1.23+ 泛型、BoltDB 和 Expr-lang 实现。提供类型安全的 API 和优雅的查询体验。

✨ 核心特性

🔒 类型安全

  • Go 1.23+ 泛型支持:编译时类型检查,零运行时类型错误
  • 智能类型转换:自动处理复杂数据类型序列化
  • IDE 友好:完整的代码补全和类型推导

🚀 高性能

  • 索引优化:最左前缀索引,支持复杂查询优化
  • 并发安全:读写锁分离,支持高并发读操作
  • 内存优化:减少反射使用,字符串操作优化

🎯 多层次API设计

  • 传统 API:简单直接,适合简单查询和向后兼容
  • 类型安全 API:编译时类型检查,适合常规查询
  • 表达式风格 API:优雅的链式操作,适合复杂查询

🔧 扩展性

  • 插件化存储:支持自定义存储引擎
  • 表达式引擎:基于 Expr-lang 的复杂条件查询
  • 向后兼容:平滑升级,新旧 API 共存

📦 安装

go get cnb.cool/zishuo/kv2doc

要求:Go 1.23 或更高版本

🚀 快速开始

三种 API 风格对比

package main

import (
    "fmt"
    "cnb.cool/zishuo/kv2doc"
)

// User 定义用户结构体
type User struct {
    Name     string `json:"name"`
    Email    string `json:"email"`
    Age      int    `json:"age"`
    IsActive bool   `json:"is_active"`
}

func main() {
    // 创建数据库
    db, _ := kv2doc.NewDB("demo.db")
    defer db.Close()

    // 方式1:传统 API(向后兼容)
    // 适合:简单查询、动态字段、遗留系统
    id, _ := db.Add("users", kv2doc.Doc{
        "name":      "张三",
        "age":       "25",
        "is_active": "true",
    })
    docs, _ := db.Query("users").
        Eq("is_active", "true").
        Gt("age", "20").
        List()
    fmt.Printf("传统 API:找到 %d 个用户\n", len(docs))

    // 方式2:类型安全 API(推荐日常使用)
    // 适合:业务开发、需要类型检查、IDE友好
    users := kv2doc.NewCollection[User](db, "users")
    user := User{
        Name:     "李四",
        Age:      30,
        IsActive: true,
    }
    users.Insert(user)

    activeUsers, _ := users.Query().
        Eq("is_active", true).
        Gt("age", 25).
        Find()

    for _, u := range activeUsers {
        fmt.Printf("类型安全:%s (%d岁)\n", u.Data.Name, u.Data.Age)
    }

    // 方式3:表达式风格 API(最优雅)
    // 适合:复杂查询、优雅语法、最佳可读性
    results, _ := users.Expr().
        WhereEq("is_active", true).        // 简洁的等值查询
        WhereBetween("age", 20, 35).       // 范围查询
        WhereIn("status", []string{"normal", "vip"}). // IN 查询
        OrderByAsc("age").                 // 排序
        Page(1, 10).                       // 分页
        Find()

    fmt.Printf("表达式 API:找到 %d 个符合条件的用户\n", len(results))

    // 💡 更多优雅用法
    // 简化语法:Where("is_active", true) 等价于 WhereEq("is_active", true)
    // 操作符语法:Where("age", ">", 25)
    // OR 条件:WhereOr("role", "admin")
    // 复杂组合:WhereGroup("OR", conditions...)
}

🎨 优雅查询 API 详解

💎 表达式风格 API(推荐新项目)

表达式风格 API 提供最优雅的语法,支持链式调用和丰富的查询条件:

users := kv2doc.NewCollection[User](db, "users")

// 🌟 基础优雅语法
results, _ := users.Expr().
    WhereEq("is_active", true).           // ✨ 等值查询
    WhereBetween("age", 18, 65).          // ✨ 范围查询
    WhereIn("status", []string{"normal", "vip"}). // ✨ IN 查询
    WhereLeftLike("name", "张").          // ✨ 前缀匹配
    OrderByAsc("age").                    // ✨ 排序
    Page(1, 20).                          // ✨ 分页
    Find()

// 🌟 简化语法(更简洁)
simple, _ := users.Expr().
    Where("is_active", true).             // 等价于 WhereEq
    Where("age", ">", 25).                // 带操作符
    Find()

// 🌟 复杂逻辑组合
complex, _ := users.Expr().
    WhereEq("is_active", true).           // 活跃用户 AND
    WhereOr("role", "admin").             // 或者是管理员
    WhereBetween("age", 25, 60).          // 年龄范围
    OrderByDesc("created_at").            // 最新优先
    Find()

// 🌟 分组条件 - 支持 (A AND B) OR (C AND D)
grouped, _ := users.Expr().
    WhereGroup("OR",
        kv2doc.And(                       // 活跃VIP用户
            kv2doc.Eq("is_active", true),
            kv2doc.Eq("status", "vip"),
        ),
        kv2doc.And(                       // 或年轻管理员
            kv2doc.Eq("role", "admin"),
            kv2doc.Lt("age", 30),
        ),
    ).Find()

🎯 查询条件完整清单

方法说明示例索引优化
WhereEq(field, value)等于WhereEq("name", "张三")✅ 快速
Where(field, value)等于简写Where("age", 25)✅ 快速
Where(field, op, value)带操作符Where("age", ">", 18)❌ 扫描
WhereGt/Gte/Lt/Lte比较操作WhereGt("age", 18)❌ 扫描
WhereLike模糊匹配WhereLike("name", "张")❌ 扫描
WhereLeftLike前缀匹配WhereLeftLike("name", "张")✅ 快速
WhereIn/NotIn包含/排除WhereIn("status", []string{"active"})✅ 快速
WhereBetween范围查询WhereBetween("age", 18, 65)❌ 扫描
WhereNull/NotNull空值检查WhereNotNull("email")❌ 扫描
WhereOr(field, value)OR 条件WhereOr("role", "admin")❌ 扫描

🔄 与现有 API 的兼容性

// 1️⃣ 传统 API(完全向后兼容)
docs, _ := db.Query("users").Eq("is_active", "true").List()

// 2️⃣ 类型安全 API(常规业务推荐)
typedResults, _ := users.Query().Eq("is_active", true).Find()

// 3️⃣ 表达式 API(复杂查询推荐)
expressiveResults, _ := users.Expr().WhereEq("is_active", true).Find()

// 💡 三种API可以在同一项目中混用,根据场景选择最合适的

📊 性能优化建议

// ✅ 高性能查询(利用索引)
users.Expr().WhereEq("email", "user@example.com")      // 精确匹配
users.Expr().WhereLeftLike("name", "张")                // 前缀匹配
users.Expr().WhereIn("status", []string{"active"})     // IN查询

// ⚠️ 需要优化的查询(全表扫描)
users.Expr().WhereLike("name", "三")                    // 中间匹配
users.Expr().WhereGt("age", 25)                        // 范围查询

// 💡 优化策略:将高选择性条件放在前面
users.Expr().
    WhereEq("email", email).              // 高选择性优先
    WhereGt("age", 18).                   // 低选择性后置
    Find()

完整示例:实际业务场景

package main

import (
    "fmt"
    "log"
    "cnb.cool/zishuo/kv2doc"
)

// User 用户模型
type User struct {
    Name     string   `json:"name"`
    Email    string   `json:"email"`
    Age      int      `json:"age"`
    IsActive bool     `json:"is_active"`
    Status   string   `json:"status"`
    Role     string   `json:"role"`
    Tags     []string `json:"tags"`
}

func main() {
    // 创建数据库
    db, err := kv2doc.NewDB("app.db")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    // 创建类型安全的集合
    users := kv2doc.NewCollection[User](db, "users")

    // 插入测试数据
    testUsers := []User{
        {Name: "张三", Age: 25, IsActive: true, Status: "normal", Role: "user"},
        {Name: "李四", Age: 30, IsActive: false, Status: "vip", Role: "admin"},
        {Name: "王五", Age: 35, IsActive: true, Status: "normal", Role: "user"},
    }

    bulk := users.Bulk()
    for _, user := range testUsers {
        bulk.Insert(user)
    }
    ids, _ := bulk.Execute()
    fmt.Printf("批量插入 %d 个用户\n", len(ids))

    // 🔍 场景1:查找活跃的年轻用户
    youngActives, _ := users.Expr().
        WhereEq("is_active", true).
        WhereLt("age", 30).
        OrderByAsc("age").
        Find()

    fmt.Printf("\n活跃年轻用户 (%d人):\n", len(youngActives))
    for _, u := range youngActives {
        fmt.Printf("  - %s (%d岁)\n", u.Data.Name, u.Data.Age)
    }

    // 🔍 场景2:复杂业务查询
    businessResults, _ := users.Expr().
        WhereEq("is_active", true).                    // 活跃用户
        WhereIn("status", []string{"normal", "vip"}).  // 正常状态
        WhereBetween("age", 20, 40).                   // 核心年龄段
        WhereOr("role", "admin").                      // 或管理员
        OrderByDesc("age").                            // 年龄降序
        Page(1, 10).                                   // 分页
        Find()

    fmt.Printf("\n业务查询结果 (%d人):\n", len(businessResults))
    for _, u := range businessResults {
        fmt.Printf("  - %s (%d岁, %s, %s)\n",
            u.Data.Name, u.Data.Age, u.Data.Status, u.Data.Role)
    }

    // 📊 统计信息
    total, _ := users.Count()
    active, _ := users.Expr().WhereEq("is_active", true).Count()
    vips, _ := users.Expr().WhereEq("status", "vip").Count()

    fmt.Printf("\n📊 统计信息:\n")
    fmt.Printf("  总用户数: %d\n", total)
    fmt.Printf("  活跃用户: %d\n", active)
    fmt.Printf("  VIP用户: %d\n", vips)

    // 🐛 调试:查看生成的查询
    query := users.Expr().
        WhereEq("is_active", true).
        WhereBetween("age", 25, 35)

    fmt.Printf("\n🐛 调试SQL: %s\n", query.ToSQL())
}

📚 API 选择指南

🎯 快速选择决策

场景推荐 API理由示例
🆕 新项目表达式风格最优雅,功能最强users.Expr().WhereEq("status", "active")
💼 业务开发类型安全平衡性能与易用性users.Query().Eq("is_active", true)
🔄 遗留项目传统 API向后兼容,零迁移成本db.Query("users").Eq("status", "active")
🔍 复杂查询表达式风格支持复杂逻辑组合users.Expr().WhereGroup("OR", ...)
简单查询任意选择三种API性能相当根据团队偏好选择

🌊 API 层次与演进路径

🏗️  kv2doc 架构
│
├── 🔧 传统 API (v1.0) - 向后兼容
│   └── db.Query("table").Eq("field", "value")
│
├── 🛡️  类型安全 API (v2.0) - 编译时检查
│   └── collection.Query().Eq("field", value)
│
└── ✨ 表达式风格 API (v3.0) - 最优雅
    └── collection.Expr().WhereEq("field", value)

💡 演进建议:新功能使用表达式风格,现有代码保持不变

🔄 API 兼容性与迁移

// 🔄 无缝迁移 - 三种API可在同一项目中混用

func searchUsers(db *kv2doc.DB) {
    // 遗留代码保持不变
    legacyResults, _ := db.Query("users").
        Eq("status", "active").
        List()

    // 新代码使用类型安全
    users := kv2doc.NewCollection[User](db, "users")
    typedResults, _ := users.Query().
        Eq("is_active", true).
        Find()

    // 复杂查询使用表达式风格
    expressiveResults, _ := users.Expr().
        WhereEq("is_active", true).
        WhereOr("role", "admin").
        Find()

    // 💡 根据场景选择,无需一次性迁移
}

📊 语法对比 - 同一查询的三种写法

// 查询:活跃用户,年龄18-65岁,按年龄排序,取前10个

// 1️⃣ 传统 API
docs, _ := db.Query("users").
    Eq("is_active", "true").
    Gt("age", "18").
    Lt("age", "65").
    Asc("age").
    Limit(0, 10).
    List()

// 2️⃣ 类型安全 API
results, _ := users.Query().
    Eq("is_active", true).
    Gt("age", 18).
    Lt("age", 65).
    OrderBy("age", false).
    Limit(0, 10).
    Find()

// 3️⃣ 表达式风格 API(最优雅)
elegant, _ := users.Expr().
    WhereEq("is_active", true).
    WhereBetween("age", 18, 65).      // 🌟 更简洁的范围查询
    OrderByAsc("age").                // 🌟 语义更清晰
    Limit(10).                        // 🌟 更简洁的分页
    Find()

🎯 核心 API 详解

📦 Collection API - 类型安全的主力接口

Collection 是推荐的主要接口,提供完整的类型安全操作:

// 🏗️ 创建集合
users := kv2doc.NewCollection[User](db, "users")

🔧 基础 CRUD 操作

// ➕ 插入文档
id, err := users.Insert(User{
    Name: "张三",
    Age:  25,
    IsActive: true,
})

// 🔍 查找文档
user, err := users.FindByID(id)                    // 根据ID查找
allUsers, err := users.Find()                      // 查找所有

// 🔄 更新文档
err = users.Update(id, User{Name: "张三更新", Age: 26})

// 🗑️ 删除文档
err = users.Delete(id)

// 📊 统计数量
count, err := users.Count()

🔍 三种查询方式 - 从简单到优雅

// 1️⃣ 简单查询 - 快速上手
activeUsers, _ := users.Where("is_active", true).Find()

// 2️⃣ 类型安全查询 - 常规业务推荐
results, _ := users.Query().
    Eq("is_active", true).            // 等值条件
    Gt("age", 18).                    // 大于条件
    Like("name", "张").               // 模糊匹配
    OrderBy("age", false).            // 排序(false=升序)
    Limit(0, 10).                     // 分页
    Find()

// 3️⃣ 表达式风格查询 - 复杂条件最优雅 ⭐
elegantResults, _ := users.Expr().
    WhereEq("is_active", true).                    // ✨ 语义清晰
    WhereBetween("age", 18, 65).                   // ✨ 范围查询
    WhereIn("status", []string{"normal", "vip"}).  // ✨ IN 查询
    WhereOr("role", "admin").                      // ✨ OR 条件
    OrderByDesc("created_at").                     // ✨ 降序排序
    Page(1, 20).                                   // ✨ 分页
    Find()

🚄 便利方法 - 常用场景一键搞定

// 📄 分页查询
pagedUsers, _ := users.FindWithPaging(0, 10)      // 偏移量, 页大小

// 📊 排序查询
sortedUsers, _ := users.FindSorted("age", false)   // 字段, 是否降序

// 📄📊 排序+分页
results, _ := users.FindSortedWithPaging("name", true, 0, 5)

// 🎯 约束条件查询
qualifiedUsers, _ := users.FindWhere(
    kv2doc.Equal[User]("is_active", true),         // 类型安全约束
    kv2doc.GreaterThan[User]("age", 18),
)

// 📊 条件统计
activeCount, _ := users.CountWhere(
    kv2doc.Equal[User]("is_active", true),
)

⚡ 批量操作 - 高性能数据处理

// 🚀 创建批量操作
bulk := users.Bulk()

// ➕ 批量插入
newUsers := []User{
    {Name: "李四", Age: 30, IsActive: true},
    {Name: "王五", Age: 25, IsActive: false},
}

for _, user := range newUsers {
    bulk.Insert(user)                              // 加入批量队列
}

// 🔄 批量更新
bulk.Update("1", User{Name: "李四(更新)", Age: 31})

// 🗑️ 批量删除
bulk.Delete("2")

// 💥 一次性执行所有操作
ids, err := bulk.Execute()                         // 事务性执行
fmt.Printf("批量操作完成,处理了 %d 条记录\n", len(ids))

🔧 TypedDB API - 精细控制场景

适合需要跨表操作或精细控制的场景:

// 🏗️ 创建泛型数据库实例
userDB := kv2doc.NewTypedDB[User](db)

// 🎯 支持多表操作
id, _ := userDB.Insert("users", user)
id2, _ := userDB.Insert("admins", adminUser)          // 同一类型,不同表

// 🔍 跨表查询
results, _ := userDB.Query("users").
    Eq("is_active", true).
    Find()

// 🔄 流式处理大数据集
err := userDB.Query("users").ForEach(func(user *kv2doc.TypedDoc[User]) bool {
    fmt.Printf("处理用户: %s\n", user.Data.Name)
    return true                                       // 继续遍历
})

🎨 自定义类型转换

type CustomConverter struct{}

func (c *CustomConverter) ToString(v any) string {
    switch val := v.(type) {
    case time.Time:
        return val.Format(time.RFC3339)               // 时间格式化
    case []string:
        return strings.Join(val, ",")                 // 数组序列化
    default:
        return fmt.Sprintf("%v", v)
    }
}

// 🔗 使用自定义转换器
users = users.WithConverter(&CustomConverter{})

🚀 性能与高级特性

⚡ 智能索引优化

kv2doc 自动为所有字段建立索引,查询引擎智能选择最优路径:

// ✅ 索引加速查询(毫秒级响应)
users.Expr().WhereEq("email", "user@example.com")          // 🔍 精确匹配
users.Expr().WhereLeftLike("name", "张")                    // 🔍 前缀搜索
users.Expr().WhereIn("status", []string{"active", "vip"})  // 🔍 多值匹配

// ⚠️ 全表扫描查询(相对较慢,但仍然高效)
users.Expr().WhereLike("name", "三")                        // 🔄 模糊匹配
users.Expr().WhereBetween("age", 25, 35)                   // 🔄 范围查询

// 💡 性能优化技巧:将高选择性条件置前
users.Expr().
    WhereEq("email", email).                               // 高选择性优先
    WhereBetween("age", 18, 65).                          // 低选择性后置
    Find()

🐛 查询调试与优化

// 📊 查看查询执行计划
query := users.Expr().
    WhereEq("is_active", true).
    WhereBetween("age", 25, 35)

fmt.Printf("🔍 查询SQL: %s\n", query.ToSQL())
// 输出: FROM users WHERE (is_active == "true") AND (age BETWEEN 25 AND 35)

// 📈 性能监控
start := time.Now()
results, _ := query.Find()
duration := time.Since(start)
fmt.Printf("⏱️  查询耗时: %v, 结果数量: %d\n", duration, len(results))

🔒 并发安全保障

kv2doc 内置读写锁,天然支持高并发场景:

// 🎯 多协程安全并发读取
for i := 0; i < 10; i++ {
    go func(id int) {
        users, _ := userCollection.Find()
        fmt.Printf("协程 %d: 读取到 %d 个用户\n", id, len(users))
    }(i)
}

// ✍️ 写操作自动加锁保护
go func() {
    userCollection.Insert(User{Name: "新用户"})              // 线程安全
}()

// 💡 最佳实践:读多写少的场景性能最佳

📊 API 参考

核心类型

类型描述示例
DB数据库实例db, _ := kv2doc.NewDB("app.db")
Collection[T]类型安全的集合操作users := NewCollection[User](db, "users")
TypedDB[T]泛型数据库操作userDB := NewTypedDB[User](db)
TypedDoc[T]泛型文档包装用户数据的文档结构
Doc传统文档 (map[string]string)doc := Doc{"name": "张三"}

Collection[T] 方法

基础操作

方法功能描述返回值
Insert(data T)插入文档(string, error)
Update(id, data T)更新文档error
Delete(id string)删除文档error
FindByID(id string)根据ID查找(*TypedDoc[T], error)
Find()查找所有文档([]*TypedDoc[T], error)
Count()统计文档数量(int64, error)

查询方法

方法功能描述返回值
Where(field, value)简单条件查询*TypedQuery[T]
Query()创建类型安全查询构建器*TypedQuery[T]
Expr()创建表达式风格查询构建器*EnhancedQuery[T]
FindWhere(constraints...)约束条件查询([]*TypedDoc[T], error)
FindWithPaging(offset, size)分页查询([]*TypedDoc[T], error)
FindSorted(field, desc)排序查询([]*TypedDoc[T], error)
FindSortedWithPaging(field, desc, offset, size)排序+分页查询([]*TypedDoc[T], error)

批量操作

方法功能描述返回值
Bulk()创建批量操作*TypedBulk[T]

TypedQuery[T] 方法

条件查询

方法功能描述索引利用
Eq(field, value)等于查询✅ 利用索引
Ne(field, value)不等于查询❌ 全表扫描
Gt(field, value)大于查询❌ 全表扫描
Gte(field, value)大于等于查询❌ 全表扫描
Lt(field, value)小于查询❌ 全表扫描
Lte(field, value)小于等于查询❌ 全表扫描
Like(field, value)模糊匹配❌ 全表扫描
LeftLike(field, value)前缀匹配✅ 利用索引
RightLike(field, value)后缀匹配❌ 全表扫描

排序和分页

方法功能描述返回值
OrderBy(field, desc)排序*TypedQuery[T]
Limit(offset, size)分页*TypedQuery[T]

执行查询

方法功能描述返回值
First()获取第一个文档(*TypedDoc[T], error)
Find()获取所有匹配文档([]*TypedDoc[T], error)
Count()统计匹配数量(int64, error)
ForEach(fn)遍历匹配文档error

约束条件 API

函数功能描述示例
Equal[T](field, value)等值约束Equal[User]("age", 25)
GreaterThan[T](field, value)大于约束GreaterThan[User]("age", 18)
LessThan[T](field, value)小于约束LessThan[User]("age", 60)

传统 API(向后兼容)

方法功能描述返回值
NewDB(path)创建/打开数据库(*DB, error)
ByStore(store)使用自定义存储引擎*DB
Add(table, doc)插入文档(string, error)
Edit(table, id, doc)更新文档error
Delete(table, id)删除文档error
Query(table)创建查询*Query
Bulk(table)创建批量操作*Bulk
Drop(table)删除表error

🏗️ 架构设计

存储结构

kv2doc 使用键值对存储,自动为每个字段建立索引:

文档存储示例

假设有一个用户文档:

{
  "_id": "123",
  "name": "张三",
  "age": "25",
  "email": "zhangsan@example.com"
}

内部存储结构

键类型用途
主键p/_id/123{"_id":"123","name":"张三",...}存储完整文档
索引f/name/张三/123123姓名索引
索引f/age/25/123123年龄索引
索引f/email/zhangsan@example.com/123123邮箱索引

查询优化

索引扫描(高性能)

// 利用索引的查询
users.Query().Eq("email", "zhangsan@example.com")     // 精确匹配
users.Query().LeftLike("name", "张")                   // 前缀匹配

全表扫描(低性能)

// 需要全表扫描的查询
users.Query().Like("name", "三")                       // 中间匹配
users.Query().Gt("age", 18)                          // 范围查询

并发模型

  • 读操作:支持多个 goroutine 并发读取
  • 写操作:使用写锁保证数据一致性
  • 事务:每个操作都有事务保障

🚀 性能优化建议

1. 合理使用索引

// ✅ 推荐:利用索引
users.Query().Eq("email", email)          // 精确查找
users.Query().LeftLike("name", prefix)    // 前缀搜索

// ❌ 避免:全表扫描
users.Query().Like("name", substring)     // 中间匹配
users.Query().Gt("created_at", timestamp) // 范围查询

2. 使用批量操作

// ✅ 推荐:批量插入
bulk := users.Bulk()
for _, user := range manyUsers {
    bulk.Insert(user)
}
bulk.Execute() // 一次事务完成

// ❌ 避免:逐个插入
for _, user := range manyUsers {
    users.Insert(user) // 每次都是独立事务
}

3. 合理分页

// ✅ 推荐:数据库层分页
users.Query().Limit(offset, pageSize).Find()

// ❌ 避免:应用层分页
allUsers, _ := users.Find()
pagedUsers := allUsers[offset:offset+pageSize]

🔌 自定义存储引擎

kv2doc 支持插件化存储引擎,只需实现 Store 接口:

type Store interface {
    CreateTable(table string) error
    DropTable(table string) error
    SetKV(table string, kvs []KV) error
    GetKV(table, key string) (KV, error)
    ScanKV(table, prefix string, handle func(key string, value []byte) bool) error
    NextID(table string) (string, error)
}

示例:自定义内存存储

type MemoryStore struct {
    data map[string]map[string][]byte
    sequences map[string]uint64
    mutex sync.RWMutex
}

func (m *MemoryStore) CreateTable(table string) error {
    m.mutex.Lock()
    defer m.mutex.Unlock()

    if m.data[table] == nil {
        m.data[table] = make(map[string][]byte)
    }
    return nil
}

// 实现其他接口方法...

// 使用自定义存储
db := kv2doc.ByStore(&MemoryStore{
    data: make(map[string]map[string][]byte),
    sequences: make(map[string]uint64),
})

🤝 贡献指南

我们欢迎社区贡献!请查看 贡献指南 了解详情。

开发环境设置

# 克隆仓库
git clone https://cnb.cool/zishuo/kv2doc.git
cd kv2doc

# 安装依赖
go mod tidy

# 运行测试
go test ./...

# 检查代码质量
go vet ./...

🎉 总结

kv2doc 为 Go 开发者提供了从简单到优雅的三层API设计:

✨ 选择你的风格

// 🔧 传统风格 - 向后兼容,快速迁移
db.Query("users").Eq("status", "active").List()

// 🛡️ 类型安全 - 编译时检查,IDE友好
users.Query().Eq("is_active", true).Find()

// 💎 表达式风格 - 最优雅,功能最强
users.Expr().WhereEq("is_active", true).WhereBetween("age", 18, 65).Find()

🚀 核心优势

  • 🎯 三种API,任君选择 - 从传统到现代,满足不同场景需求
  • ✨ 表达式API最优雅 - WhereEq, WhereBetween, WhereOr 语义清晰
  • 🔒 类型安全 - Go 1.23+ 泛型支持,编译时错误检查
  • ⚡ 高性能 - 智能索引,并发安全,内存优化
  • 🔄 零迁移成本 - 完美向后兼容,新旧API共存

🎨 推荐用法

// 🆕 新项目推荐:表达式风格API
results, _ := users.Expr().
    WhereEq("is_active", true).        // 简洁优雅
    Where("age", ">", 18).             // 灵活操作符
    WhereIn("role", []string{"user", "admin"}). // 丰富条件
    OrderByDesc("created_at").         // 语义清晰
    Page(1, 20).                       // 简单分页
    Find()

// 💼 日常业务:类型安全API
users.Query().Eq("is_active", true).Find()

// 🔄 遗留系统:传统API
db.Query("users").Eq("is_active", "true").List()

📄 许可证

本项目采用 MIT 许可证。详情请参阅 LICENSE 文件。

🙏 致谢

  • BoltDB - 提供可靠的键值存储
  • Expr - 提供强大的表达式引擎
  • Go 团队 - 提供优秀的泛型支持

开始你的优雅查询之旅吧! 🚀