前言: github地址 asdine/storm
asdine/storm 是golang 开发的一个 orm工具. 内置嵌入式数据库为 golang 的流行 K/V 数据库 bbolt
创建数据结构
type User struct { ID int //主键,默认 ID 值为主键, 申明其他类型为主键: `storm:"id"` Group string `storm:"index"` //索引 Email string `storm:"unique"` // 不可重复 Name string // 普通字段, 不会创建索引 Age int }
打开数据库
db, err := storm.Open("my.db") defer db.Close()
CRUD 以及数据表操作
//---------------以下是 数据库 操作---------------------- // Init 为给定结构创建索引和存储桶 Init(data interface{}) error eg: err := db.Init(new(User)) // ReIndex 重建存储桶的所有索引. 优化数据库使用 ReIndex(data interface{}) error eg: db.ReIndex(new(User) // 保存结构体数据 Save(data interface{}) error eg: err := db.Save(&SimpleUser{ID: 10, Name: "John"}) // 更新结构体数据, 可以同时修改多个数据 Update(data interface{}) error eg: err = db.Update(&User{ID: 10, Name: "Jack"}) // 更新单个字段 UpdateField(data interface{}, fieldName string, value interface{}) error eg: err = db.UpdateField(&User{ID: 11}, "Name", "Jack") 附0值 eg: err = db.UpdateField(&User{ID: 10}, "Age", int(0)) // 删除整个表 Drop(data interface{}) error eg: err = db.From("b1").Drop("b2") // DeleteStruct 从关联的存储表中删除结构 DeleteStruct(data interface{}) error eg: u1 := IndexedNameUser{ID: 10, Name: "John", age: 10} err = db.DeleteStruct(&u1)
普通查询
提供的方法
One(fieldName string, value interface{}, to interface{}) error Find(fieldName string, value interface{}, to interface{}, options ...func(q *index.Options)) error // AllByIndex 获取在指定索引中索引的存储桶的所有记录 AllByIndex(fieldName string, to interface{}, options ...func(*index.Options)) error // 如果没有记录,它不会返回任何错误,并且"to"参数设置为空切片 All(to interface{}, options ...func(*index.Options)) error // 返回一个 query 对象, 使用 tree.go 提供的方法. Select(matchers ...q.Matcher) Query // 按指定范围内的指定索引返回一个或多个记录 Range(fieldName string, min, max, to interface{}, options ...func(*index.Options)) error // 返回一个或多个记录,其给定字段以指定的前缀开头 Prefix(fieldName string, prefix string, to interface{}, options ...func(*index.Options)) error // 计数存储桶的所有记录 Count(data interface{}) (int, error)
type User struct{ Name string `json:"name"` Age int `json:"age"` }
案例
- One
//定义接收参数 var user User // 如果查询到符合 Name = John 的数据, 赋值给 user 变量 // 如果查询不到数据, 返回 err = storm.ErrNotFound err = db.One("Name", "John", &user)
- Find
//定义接收参数数组 var users []User // 如果查询到符合 Name = John 的数据, 赋值给 users 变量 // 如果查询不到数据, 返回 err = storm.ErrNotFound //可以添加 option 参数 err = db.Find("Name", "John", &users) err = db.One("Name", "John", &user, storm.Limit(10), storm.Skip(10), storm.Reverse())
- AllByIndex
//定义接收参数数组 var users []User // 根据索引,查询全部的数据, // 如果查询不到数据, 返回 err = storm.ErrNotFound err = db.AllByIndex("Name", &users)
- All
//定义接收参数数组 var users []User // 查询全部的数据 // 如果查询不到数据, 返回 err = storm.ErrNotFound //如果没有记录,它将不返回任何错误,并且"to"参数设置为空切片。 err = db.All(&users)
- Select 高级查询用法
//定义接收参数数组 var users []User //根据Matcher构造Query 对象 query := db.Select(q.Gte("ID", 10), q.Lte("ID", 100)) query.Find(&users) //其他方法参考 query.go
- Range 范围查询
//定义接收参数数组 var users []User //设定一个范围, 查询 // 如果查询不到数据, 返回 err = storm.ErrNotFound err := db.Range("Age", 10, 21, &users)
- Prefix 模糊查询
//定义接收参数数组 var users []User //设定字符前缀, 查询满足前缀给定值的数据 // 如果查询不到数据, 返回 err = storm.ErrNotFound err := db.Prefix("Name", "Jo", &users)
- Count 查询数据量
//查询bucket 中的数据总量 //如果数据量为0, 不会返回 err. count, err := db.Prefix(&User{})
高级查询 匹配器 Matcher 接口
// Eq 匹配器,检查给定字段名(field) 是否等于给定值(value) 。 func Eq(field string, v interface{}) Matcher { return NewFieldMatcher(field, &cmp{value: v, token: token.EQL}) } eg: q.Eq("Name","Jone") // EqF 匹配器, 检查给定字段名 field1是否等于给定的另一个字段名称field2 func EqF(field1, field2 string) Matcher { return NewField2FieldMatcher(field1, field2, token.EQL) } // StrictEq 匹配器, 检查给定字段名field是否深度等于(deeply equal) 给定的值 func StrictEq(field string, v interface{}) Matcher { return NewFieldMatcher(field, &strictEq{value: v}) } // Gt 匹配器, 检查给定字段名field是否大于给定的值 func Gt(field string, v interface{}) Matcher { return NewFieldMatcher(field, &cmp{value: v, token: token.GTR}) } // GtF 匹配器, 检查给定字段名 field1是否大于给定的另一个字段名称field2 func GtF(field1, field2 string) Matcher { return NewField2FieldMatcher(field1, field2, token.GTR) } // Gte 匹配器, 检查给定字段名field是否大于等于 >= 给定的值 func Gte(field string, v interface{}) Matcher { return NewFieldMatcher(field, &cmp{value: v, token: token.GEQ}) } // GteF 匹配器, 检查给定字段名 field1是否大于或等于给定的另一个字段名称field2 func GteF(field1, field2 string) Matcher { return NewField2FieldMatcher(field1, field2, token.GEQ) } // Lt 匹配器, 检查给定字段名field是否小于给定的值 func Lt(field string, v interface{}) Matcher { return NewFieldMatcher(field, &cmp{value: v, token: token.LSS}) } // LtF 匹配器, 检查给定字段名 field1是否小于给定的另一个字段名称field2 func LtF(field1, field2 string) Matcher { return NewField2FieldMatcher(field1, field2, token.LSS) } // Lte 匹配器, 检查给定字段名field是否小于等于给定的值 func Lte(field string, v interface{}) Matcher { return NewFieldMatcher(field, &cmp{value: v, token: token.LEQ}) } // LteF 匹配器, 检查给定字段名 field1是否小于等于给定的另一个字段名称field2 func LteF(field1, field2 string) Matcher { return NewField2FieldMatcher(field1, field2, token.LEQ) } // In 匹配器, 检查给定字段名field是否等于给定的切片中的一个值 // v 必须是一个切片. func In(field string, v interface{}) Matcher { return NewFieldMatcher(field, &in{list: v}) } eg: q.Eq("Name",["a","b","c"]) // True 匹配器, 总是返回 true func True() Matcher { return &trueMatcher{} } // Or 匹配器, 传入多个 Matcher 对象, 或的关系 func Or(matchers ...Matcher) Matcher { return &or{children: matchers} } eg: q.Or( q.Eq("Name":"Jone" ), q.Eq("Name":"Zach")) // And 匹配器, 传入多个 Matcher 对象, 全部满足, 与的关系 func And(matchers ...Matcher) Matcher { return &and{children: matchers} } // Not 匹配器, 传入多个 Matcher 对象, 全部不满足, 非的关系 func Not(matchers ...Matcher) Matcher { return ¬{children: matchers} } // Re 匹配器, 重新创建一个正则匹配规则, 检查给定的字段 field 是否匹配给定的正在规则 // 请注意,这仅支持类型字符串或 [字节]的字段。 // 第二个参数写入正则的字符串表达式 func Re(field string, re string) Matcher { *** } eg: q.Re("A", "\\d+")
高级查询 匹配器 Query 接口
提供的方法
// 按给定编号跳过匹配记录 Skip(int) Query // 返回指定数量的数据 Limit(int) Query // 按给定字段从左到右的降序排列。 OrderBy(...string) Query eg: q.OrderBy("Name", "Age") // 切换排序方案: 降序 <--> 升序 Reverse() Query // 表名称 Bucket(string) Query // 查询匹配列表 Find(interface{}) error // 得第一条匹配记录 First(interface{}) error // 删除所有匹配的记录 Delete(interface{}) error // 所有匹配记录的数量 Count(interface{}) (int, error) // 返回所有记录的原始数据. 未进行解码操作 Raw() ([][]byte, error) // 对每个原始元素执行给定的功能 RawEach(func([]byte, []byte) error) error // 对每个元素执行给定的功能 Each(interface{}, func(interface{}) error) error
KV数据库操作
直接通过数据 Key 操作数据库, 提供的方法有:
// 获取第 N 个元素 // 如果查询不到数据, 返回 err = storm.ErrNotFound Get(bucketName string, key interface{}, to interface{}) error eg: 查询第10条元素 u2 := IndexedNameUser{} err = db.Get("IndexedNameUser", 10, &u2) // 添加 KV 数据库的值 Set(bucketName string, key interface{}, value interface{}) error eg: err := db.Set("files", "myfile.csv", "a,b,c,d") // 删除KV 数据库的值 Delete(bucketName string, key interface{}) error eg: err = db.Delete("files", "myfile.csv") // 获取 key 值为 bytes 类型的 value 值 GetBytes(bucketName string, key interface{}) ([]byte, error) // 设置 key 值为 bytes 类型的 value 值 SetBytes(bucketName string, key interface{}, value []byte) error // KeyExists 判断 key 值是否已经被创建 KeyExists(bucketName string, key interface{}) (bool, error)
来源:https://www.cnblogs.com/xuange306/p/12630549.html