「这是我参与11月更文挑战的第16天,活动详情查看:2021最后一次更文挑战」。
简介
Storm是嵌入数据库BoltDB的orm
官方宣称BoltDB目前是稳定可靠,可用于生产环境,支持最大1TB数据的嵌入数据库。使用的公司有Shopify和Heroku等
Storm官网: github.com/asdine/stor…
Storm特点
- 支持创建索引
- 支持多方式的存储和查找数据
- 支持高级查询
BoltDB相关资源:
- BoltDB分支(因主线停止开发): github.com/etcd-io/bbo…
- 源码阅读小结(中文): github.com/ZhengHe-MD/…
- 命令行查看数据工具: github.com/br0xen/bolt…
- web界面查看数据工具: github.com/evnix/boltd…
安装
先使用go将包下载到本地
go get github.com/asdine/storm/v3
在代码编辑器里面引入既可使用
import "github.com/asdine/storm/v3"
使用
初始化
Open函数默认创建的db文件权限是0600(属主读写),1秒超时的选项,可以自行传值修改
//db, err := storm.Open("my.db", storm.BoltOptions(0600, &bolt.Options{Timeout: 1 * time.Second}))
使用默认值初始化,会在项目当前目录创建一个my.db的文件
var (
db *storm.DB
err error
)
func init() {
db, err = storm.Open("my.db")
if err != nil {
panic(err)
}
}
数据模型
- storm会搜索id或ID做为主键
- storm:"index" 索引字段
- storm:"unique" 唯一字段
- storm:"increment" 自增字段,increment=10从10开始自增
- storm:"inline" 内联字段,结构体嵌套时使用
- 没有标识,说明没有唯一属性,也没有索引
type User struct {
ID int
Group string `storm:"index"`
Email string `storm:"unique"`
Name string
Age int `storm:"index"`
CreatedAt time.Time `storm:"index"`
}
写入数据
因为我们没有开启批量写入模式,所以这里只能一条条的写入
为了方便后续的操作,这里写入三条略微不同的数据
user := User{
ID: 1,
Group: "frontend",
Email: "zhangsan@libaigo.com",
Name: "zhangsan",
Age: 21,
CreatedAt:time.Now(),
}
user2 := User{
ID: 2,
Group: "frontend",
Email: "lisi@libaigo.com",
Name: "lisi",
Age: 32,
CreatedAt:time.Now(),
}
user3 := User{
ID: 3,
Group: "backend",
Email: "zhaowu@libaigo.com",
Name: "zhaowu",
Age: 31,
CreatedAt:time.Now(),
}
_ = db.Save(&user)
_ = db.Save(&user2)
_ = db.Save(&user3)
简单查询
- One方法 获取一条数据
- Find方法 获取多条数据
- All方法 获取全部数据
- Range方法 获取范围内数据
- Prefix方法 获取前缀匹配数据
var u User
_ = db.One("Name", "zhangsan", &u)
fmt.Println("单条",u)
var u2 []User
_ = db.Find("Group", "frontend", &u2)
fmt.Println("多条",u2)
var u3 []User
_ = db.All(&u3)
fmt.Println("全部",u3)
var u4 []User
_ = db.Range("Age", 30, 40, &u4)
fmt.Println(u4)
var u5 []User
_ = db.Prefix("Name", "z", &u5)
fmt.Println(u5)
跳过,限制,取反
Skip,Limit,Reverse可以在多条,全部,范围查询中进一步过滤出需要的数据范围
var u6 []User
_ = db.Find("Group", "frontend", &u6, storm.Skip(10))
_ = db.Find("Group", "frontend", &u6, storm.Limit(10))
_ = db.Find("Group", "frontend", &u6, storm.Reverse())
_ = db.Find("Group", "frontend", &u6, storm.Limit(10), storm.Skip(10), storm.Reverse())
_ = db.All(&u6, storm.Limit(10), storm.Skip(10), storm.Reverse())
_ = db.AllByIndex("CreatedAt", &u6, storm.Limit(10), storm.Skip(10), storm.Reverse())
_ = db.Range("Age", 10, 21, &u6, storm.Limit(10), storm.Skip(10), storm.Reverse())
更新数据
- Update方法 更新多个字段数据,根据ID来匹配行
- UpdateField方法 更新单个字段数据,根据ID来匹配行
_ = db.Update(&User{ID:1,Name:"zhangsan",Age:19})
_ = db.UpdateField(&User{ID:3},"Age", 26)
高级查询
复杂的查询Storm写在Select方法中,而该方法中封装匹配器在q包中,所以在使用前需要引入包 import "github.com/asdine/storm/v3/q"
该包中的方法类似于关系运算符和布尔运算符
- Eq 等于
- Gt 大于
- Lte 小于或等于
- Re 匹配前缀
- In 精确匹配
使用Select方法接收匹配器,并使用q.And包装,并支持方法链路,最后返回一个查询器
q.Eq("Name", "lisi")
q.Gt("Age", 7)
q.Lte("Age", 77)
q.Re("Name", "^z")
q.In("Group", []string{"frontend", "backend"})
//查询例子
query := db.Select(q.Gte("Age", 7), q.Lte("Age", 77)).
Limit(10).Skip(0).OrderBy("Age").Reverse()
var u8 []User
err = query.Find(&u8)
fmt.Println(u8)
删除
- DeleteStruct方法 删除表里面的数据
- Drop方法 删除表
- Init方法 初始化表(用于程序启动固定表结构)
- ReIndex方法 重建索引(用于表结构变更后)
_ = db.DeleteStruct(&user)
err := db.Drop(&User{})
fmt.Println(err)
err = db.Init(&User{})
err = db.ReIndex(&User{})