zoukankan      html  css  js  c++  java
  • asdine/storm学习笔记

    前言: github地址 asdine/storm
    asdine/storm 是golang 开发的一个 orm工具. 内置嵌入式数据库为 golang 的流行 K/V 数据库 bbolt

    创建数据结构

    storm定义数据接口时设定了4个关键字作为模型的tag.

    storm:"id" // 此字段配置为主键
    storm:"id,increment" //此字段必须为整型, 在新增数据时,这个字段会自动累增,不需要手动设置主键
    storm:"index" //将此字段设定为索引字段
    storm:"unique" //将此字段设定为 值不可重复的字段

    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.In("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 &not{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)
    
  • 相关阅读:
    愤怒
    Eclipse的调试功能的10个小窍门
    PL/SQL之基础篇
    PL/SQL之高级篇
    luogu P1015 回文数
    Noip2011 提高组 Day1 T3 Mayan游戏
    各种各样的——玄学卡常技巧
    北京清北 综合强化班 Day5
    [UVA12003] Array Transformer(分块,二分,暴力)
    [POJ3468] A Simple Problem with Integers(分块)
  • 原文地址:https://www.cnblogs.com/shuiche/p/12630549.html
Copyright © 2011-2022 走看看