db#数据库
tsbApi.db.* API
由于传统的web数据库存储方式无法达到更好的数据存储和持久化效果,且容易被清理浏览器缓存时误杀,所以我们提供了db接口,方便大家的应用做持久化。
db接口采用PouchDB(pdb)做底层实现,并提供了pdb的常规接口。具体可参考文档。
注意:
1.pdb本身是一个数据库适配器,他在不同的环境下会使用不同的底层。例如在浏览器web下使用indexDB,而在nodejs下使用levelDB,而我们轻应用则统一采用与nodejs一致的levelDB方式进行存储。
强烈建议大家在使用db之前,先去看一下clipboard.ts的写法,大部分的分页用法都有示例。可以直接cccv,大大提升编写效率。vite/packages/table/apps/clipboard/store.ts
2.由于levelDB只可在一个进程中使用。所以如果卡片与主应用采用长连接方式会锁住数据库,造成被占用后另一个无法读写数据库。
为了解决此冲突问题,所有的数据库操作,都是采用先连库后关闭的方式。每次操作都会释放掉数据库。所以应用开发者需要考虑到这个问题。
尽量规避掉需要长时间操作的操作,同时也要对数据库异常进行判断,避免出现死锁导致操作失败。
db操作
tsbApi.db.put(doc)
//创建
tsbApi.db.put({
_id:'item:1',
category:'cat1',
content:'content',
createTime:Date.now(),
updateTime:Date.now()
})
//更新
tsbApi.db.put({
_id:'item:1',
content:'content2',
updateTime:Date.now(),
...,
_rev:'...'//此字段应当从数据库内获取最新的数据得到,而不可手写
})
_id是文档的唯一标志,推荐采用命名规则[表名]:[nanoid]
,例如item:djfexe
,nanoid不容易冲突,但是易读性较差,且没有规律
更新特别注意事项:pdb要求在更新的时候,数据必须提供_rev字段,且此字段与数据库内数据最新的字段相同,否则无法写入。这是一种防止版本冲突的方式。
所以在更新之前请先试用获取方法获取到最新的数据,然后修改需要更新的字段,再使用put更新。
tsbApi.db.bulkDocs(docs)
批量添加文档
tsbApi.db.bulkDocs([
{
_id:'item:1',
...
},
{
_id:'item:2',
...
}
])
tsbApi.db.remove(id)
删除某个文档
//删除文档
tsbApi.db.remove('item:1')
tsbApi.db.allDocs(key)
//取回以item:开头的全部文档
tsbApi.db.allDocs('item:')
//取回指定id的内容
tsbApi.db.allDocs(['item:1','item:2','item:3'])
tsbApi.db.allDocsQuery(options)
有时候,默认提供的allDocs无法满足业务需求,此时可使用自由度更高的带Query的查询,具体参数作用可参考pdb文档。参数参考
tsbApi.db.allDocsQuery({
include_docs: true,
attachments: true,
startkey: 'foo',
endkey: 'foo\ufff0'
})
tsbApi.db.createIndex(index )
这个是使用find方法的前提,需要对需要查找的字段进行索引构建。参数参考
tsbApi.db.createIndex({
index: {
fields: ['type', 'createTime', 'content','searchKey'] //支持同时创建多个
}
})
tsbApi.db.find(options)
此方法支持比较复杂的查询方式,但是在查询前需要先借助createIndex创建索引。find支持正则表达式,支持排序,支持限制查询数量,建议使用条件优化查询
let dbKey = 'clipboard:item:'
let map: any = {
_id: {
$regex: new RegExp(`^${dbKey}`) //查询clipboard:item:开头的记录,约等于分表
}
}
if (this.filterType !== 'all') {
map.type = this.filterType
}
if (this.items.length > 0) {
map.createTime = {
$lt: this.items[this.items.length - 1].createTime
}
}
let rsFiltered = await tsbApi.db.find({
selector: map,
limit:10,
sort: [
{
'_id': 'desc'
}
]
})
复杂find查询条件示例
1.字段为字符串或者数组的时候,匹配=或包含在数组内的条件
查询条件:匹配以dbKey为起始的id,并且 exeName字段为字符串的时候=某个字符串,或者当exeName类型为数组的时候,包含某个字符串
tip: AI 提问描述示例(可供参考):
写一个pouchdb find的查询调节,查询数组型的字段中包含某个字符串元素,或者这个字段是一个字符串的时候,则条件为两者相等,并且id等于指定id
let map: any = {
$and: [
{
_id: {
$regex: new RegExp(`^${dbKey}`)
}
}
] //第一个条件
}
if (exeName) {
map.$and.push({
$or:
[{
exeName: {
$elemMatch: {
$regex: new RegExp(exeName)
}
},//数组包含条件,匹配例如 exeName:['a.exe','b.exe']
},
{
exeName: exeName
}
] //匹配exeName:'a.exe'
}) //增设一个数组包含或者字符串相等的条件
}