一些概念:indexedDB是HTML5标准。indexedDB的最主要优势在于,indexedDB是一个完整的数据库模型,它具有数据库应该有的库表结构,丰富的查询方式等等。除此之外,localStorage的容量在5M左右,而indexedDB达到惊人的500M。indexedDB还有可以存储arraybuffer,进程为异步等特征,这些特质都使得使用indexedDB作为前端数据存储的不二之选,localStorage降级为用于存储散列的快速读取配置项的存储工具。
缺点:api太复杂。
keyPath:localStorage是键值对;indexedDB是Object,也就是js对象。
key:indexedDB的key代表键值而非键名。
索引:indexedDB如其名,它的特色就是index(索引)。indexedDB具备了强大的索引系统,它根据keyPath创建索引,根据indexName查询对象记录,可以对一个indexName设置多个keyPath,而且还可以实现值域查询。
InDB简化indexDB操作。
安装:npm i indb
使用:
- 连接到数据库
- 打开一个store(相当于表)
- 写入或修改数据
const idb = new InDB(options) // 实例化InDB,得到一个可以连接数据库的实例
const store = idb.use('store1') // 通过use方法,打开一个store
option参数列表
在进行InDB实例化时,需要传入参数:
name: 字符串,数据库名称
version: 正整数,数据库结构的版本,调整数据库结构时,需要升级version
stores: 数组,用以定义当前数据库中每个store的结构
name: 字符串,store名称
keyPath: 字符串,store keyPath
indexes: 数组,用以定义store的索引
name: 字符串,索引名称
keyPath: 字符串,索引的keyPath
unique: boolean,该索引是否是唯一的,不允许同一个store中同索引名存在两个及以上的索引值
isKv: boolean,是否开启key-value模式,为true时keyPath和indexes无效
增:
await store.add({ id, name, age })
注意:
相当于sql中的insert操作,需要注意,indexedDB中,对add的数据格式有要求,必须符合下面其中之一
- options中没有设置autoIncrement,在add的对象中,必须包含keyPath属性,且key值相同的记录不能存在于store中
- options中设置了autoIncerment为true,那么在add对象时,不必传keyPath,add成功时,会自动为该object加上该属性,并且保持自增的效果
如果add的对象key值已经存在于store中,会报错,因此,比较常规的操作是用put代替add。
删:
await store.delete(key)
改:
await store.put({ id, name, age })
注意:
put中key值其实也遵循上面add的规律,如果autoIncrement设置为true,那么不给key时,就是添加,给key时,就是更新。
一般,在代码中我们尽量少使用autoIncrement配置,因为我们很难完全掌握数据的实际情况。我们尽量使用put,而不是add,因为代码一旦部署,它就不能修改,如果在执行中add报错,那么很可能阻塞你的程序。
查:
let value = await store.get(key)
注意:
- @param {String} key 主键值,注意,是值,不是名
- @return {Object} value
indexedDB真正强大的地方是利用索引进行查询。
注意:依赖于 index 的查询 API 需要在创建仓库时传入对应的 indexes,即使该属性已经被 keyPath 使用,也要在 indexes 中再次声明,否则无法使用下面的查询接口。
const store = new InDB({
name: 'my-idb',
stores: [
{
name: 'my-store',
keyPath: 'id',
indexes: [
{
name: '索引',
keyPath: 'age',
},
],
},
],
})
let obj = await store.find('索引', 10)//找到数据库中第一条age = 10的数据,相当于sql里面的where age=10 limit 1
注意:只有当你在创建store的时候,设置了这个索引,才能使用find去使用它