目录

  • indexedDB介绍
  • 数据库操作IDBFactory
    • 增(连接)
  • 请求操作IDBRequest
    • onsuccess
    • onerror
    • onupgradeneeded
    • result
  • 操作对象库IDBObjectStore
    • 什么是对象库
  • 事务对象IDBTransaction
    • transaction
    • 清除
    • 条件查询
    • 条件查询keyPath值
    • 对象库中数据的条数
  • 对象库遍历IDBCursor
    • 语法
    • 按照对象库的数据的keyPath进行遍历
  • 学习资料

indexedDB介绍


1)IndexedDB是浏览器提供的本地数据库,具有以下特点:

  • 键值对存储

  • 异步操作

  • 支持事务。这意味着一系列操作步骤之中,只要有一步失败,整个事务就都取消,

    数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。

    数据库几乎所有操作,都是通过事务来处理的。

  • 受浏览器同源限制。每一个数据库对应创建它的域名。

    网页只能访问自身域名下的数据库,而不能访问跨域的数据库。

  • 储存空间大。一般来说不少于 250MB,甚至没有上限。

  • 支持二进制储存。 IndexedDB 不仅可以储存字符串,还可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)。

  • 几乎所有操作都有成功和失败的监听。


2) 它包含很多对象接口:

  • 数据库:IDBDatabase 对象
  • 对象仓库:IDBObjectStore 对象
  • 操作请求:IDBRequest 对象
  • 事务: IDBTransaction 对象
  • 索引: IDBIndex 对象
  • 指针: IDBCursor 对象

等。

更多接口可在MDN上查看和学习。


3) 本篇全文两万字,内容是按照整个学习流程,从外到内进行梳理的,

几乎每个知识都会有相应示例。

初次接触可以逐步阅读,熟悉后,可以当作一个语法查阅手册。

本篇只梳理了知识点,后续将发布更多实战操作。

4) 欢迎访问自己写的一个开放了部分功能的小网站,

有建议和意见,在上面随便提。域名过期了,还没补。

http://81.68.151.74/

目前在开发网页版微信,有兴趣可以一起讨论。


数据库操作IDBFactory


增(连接)

使用数据库,就必须先创建和连接一个数据库,然后才能对数据库进行其他操作。

// 处理兼容性问题
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
// open方法创建并连接一个数据库
const request = window.indexedDB.open(dbname, dbversion)
// dbname:数据库名字
// dbversion:数据库版本号,可以不写,默认为1
// indexedDB遵守同源策略,在同一个源下,dbname是不能重复的,
// 同一个dbname,也只会存在一个对应的版本号
// 如果dbname不存在,就创建并打开;如果已存在,就直接打开
// indexedDB喜欢把一些操作称为'请求',所以用了'request'变量。

// 删除数据库
window.indexedDB.deleteDatabase(dbname);

window.indexedDB.databases()
.then(database => console.log(database))
// database是一个列表
// 列表中每一项包含数据库名称和版本号
[{"name": "ok", // 数据库名称"version": 2  // 对应版本号},{"name": "todoList","version": 1}
]

请求操作IDBRequest


打开数据库后,得到一个请求对象request

const request = window.indexedDB.open(dbname, [dbversion])
console.log('request: ', request);
// 打印内容:
{error: null,onblocked: null,onerror: null,onsuccess: null,onupgradeneeded: f,readyState: "done",result: {name: 数据库名称,version: 数据库版本号,objectStoreNames: 对象仓库名称列表},source: null,transaction: 数据库事务
}

request中有个result字段和一些on事件,可以使用该字段和相应的事件,处理请求结果。


onsuccess

打开数据库成功后执行。每次open成功后都会调用一次。

request.onsuccess = function(e) {console.log('打开数据库成功')const db = this.result;
}

onerror

打开数据库失败时执行。每次open失败后调用。

request.onerror = function(e) {console.log('打开数据库失败: ', request.error);
}

示例:

// 假设当前数据库名称为'test', version为2
// 此时,打开test版本为1的话,就会触发onerror
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
let db;
const request = window.indexedDB.open('test', 1);
request.onerror = function() {console.log('open error: ', request.error);
}
// error
open error:  DOMException: The requested version (1) is less than the existing version (2).

onupgradeneeded

监听数据库版本更新。

1)新建数据库时会调用

2)数据库版本升级时会调用

而且,该方法的调用,是在onsuccess之前执行。

request.onupgradeneeded = function(e) {const db = this.result;console.log('数据库新的版本号是:', db.version);
}

示例1:

新建数据库ok

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
let db;
const request = window.indexedDB.open('songs');
request.onerror = function() {console.log('open error: ', request.error);
}
request.onsuccess = function() {db = this.result;console.log('open success, dbbase current version: ', db.version);
}
request.onupgradeneeded = function() {console.log('open upgrade...');
}
// 打印结果:
// open upgrade...
// open success, dbbase current version:  1

示例2:

数据库版本升级时,原来默认的版本是1,现在改为2

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
let db;
const request = window.indexedDB.open('songs', 2);
request.onerror = function() {console.log('open error: ', request.error);
}
request.onsuccess = function() {db = this.result;console.log('open success, dbbase current version: ', db.version);
}
request.onupgradeneeded = function() {console.log('open upgrade...');
}
// 打印结果:
// open upgrade...
// open success, dbbase current version:  2

result

result是数据库请求对象request的属性之一,它对应的是IDBDatabase

即数据库对象。后续的操作,都是基于该对象来实现的。

看看result里都有什么?

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
let db;
const request = window.indexedDB.open('songs', 2);
request.onsuccess = function() {console.log('request: ', request.result);db = this.result;
}
// 打印结果
IDBDatabase {name: 'songs',version: 2,objectStoreNames: 对象库名称列表onabort: null,onclose: null,onerror: null,onversionchange: null
}
// 原型中还有:
{close: f, // 关闭数据库createObjectStore: f, // 创建对象库deleteObjectStore: f, // 删除对象库transaction: f // 处理事务的方法
}

操作对象库IDBObjectStore


什么是对象库

数据库可以理解为一个个数据表单组成的,其中,每一个表单,就是一个对象库。

比如,我们有一个名为职业的数据库,职业中的教师、医生、码农,都是职业中

一个下级表单,分别是一个对象库。主要是按照一定的规则操作数据。


1)语法:

// storeName 对象库名称
// option 配置项,可选的,用来设置keyPath
const objectStore = db.createObjectStore(storeName, option)// 对象库里都有哪些项,比如姓名 年龄等
// indexName 姓名 年龄等具体的项
// keyPath 该项的查询路径,一般和indexName的值一样
// option 可选,如unique,为true则表示同一个项的值不能重复
objectStore.createIndex(indexName, keyPath, option);
// 删除具体的项
objectStore.deleteIndex(indexName);

2)只能在onupgradeneeded方法中添加对象库

个人认为原因有2:

添加对象库的操作只需要在新建数据库或版本更新时进行;

onupgradeneededonsuccess优先调用,应该更早的创建好对象库,以免报错。

示例:

数据库jobs里,创建了三个对象库teacher , doctor, developer

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
let db;
const request = window.indexedDB.open('jobs');
request.onerror = function() {console.log('open error: ', request.error);
}
request.onsuccess = function() {console.log('request: ', request.result);db = this.result;
}
request.onupgradeneeded = function() {console.log('open upgrade...');db = this.result;if(!db.objectStoreNames.contains('teacher')) {db.createObjectStore('teacher', { keyPath: 'id' });objectStore.createIndex('name', 'name', { unique: true });objectStore.createIndex('age', 'age', { unique: false })}if(!db.objectStoreNames.contains('doctor')) {db.createObjectStore('doctor', { keyPath: 'id' });}if(!db.objectStoreNames.contains('developer')) {db.createObjectStore('developer', { keyPath: 'id' });}
}

db.deleteObjectStore(storeName);

事务对象IDBTransaction

对表单的每一项操作,必须通过具体的事务来完成,一个事务就是一个transaction.

事务是对象库接口的API

操作事务在request.onsuccess中完成。


transaction

事务。

语法:

// 创建事务
const transaction = db.transaction(storeNames, mode, options)
// storeNames对象库名称列表。如['teacher', 'doctor'],
// 如果只写一个对象库名称,可以写成字符串,如'teacher'
// mode 权限
// 在对象库内的数据需要变动时,需要设置权限为'readwrite',可读可写
// 在查询对象库数据时,权限可以设置为'readonly',只读模式
// options,配置项,可选的。

此时,要操作哪个对象库,就通过transaction.objectStore获取该对象库的事务

const store = transaction.objectStore(storeName);
// storeName 对象库名称

操作对象库事务的结果有成功和失败事件来监听:

// 这里的res是sotre操作对应的方法后的执行结果,后面会提到
res.onerror = function() {console.log('处理事务失败...');
}
res.onsuccess = function() {console.log('处理事务成功...');
}

往对象库内增加数据。

语法:

const res = store.add(data);
res.onerror = function() {// res.error是失败的原因console.log('处理事务失败: ', res.error);
}
res.onsuccess = function() {// res.result是增加的该项数据的keyPath值console.log('处理事务成功: ', res.result);
}

注意事项:

1)添加的数据中,必须包含keyPath值,不然就报错

Failed to execute 'add' on 'IDBObjectStore': Evaluating the object store's key path did not yield a value.

2)添加数据时,keyPath值不能重复,也不能是已经存在的keypPath值,

不然就添加失败。

假定keyPath为'id',且id的值1已经存在,此时再重复添加:
const res = store.add({ id: 1, name: 'liushishi', age: 20 });
就会触发onerror:
add data error:  DOMException: Key already exists in the object store.

示例:

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
let db;
const request = window.indexedDB.open('jobs');
request.onerror = function() {console.log('open error: ', request.error);
}
request.onsuccess = function() {console.log('request: ', request.result);db = this.result;// 增const transaction = db.transaction('teacher', 'readwrite');const store = transaction.objectStore('teacher');const res = store.add({ id: 1, name: 'dilireba', age: 18 });res.onerror = function() {console.log('add data error: ', res.error);}res.onsuccess = function() {console.log('add data success: ', res.result); // 1}
}
request.onupgradeneeded = function() {console.log('open upgrade...');db = this.result;if(!db.objectStoreNames.contains('teacher')) {const objectStore = db.createObjectStore('teacher', { keyPath: 'id' });objectStore.createIndex('name', 'name', { unique: true });objectStore.createIndex('age', 'age', { unique: false })}if(!db.objectStoreNames.contains('doctor')) {db.createObjectStore('doctor', { keyPath: 'id' });}if(!db.objectStoreNames.contains('developer')) {db.createObjectStore('developer', { keyPath: 'id' });}
}

删除对象库中的一条数据。

语法:

const res = store.delete(id)
// id是keyPath值
// 执行该方法后,会删除keyPath的值为id的那条数据。

示例:

request.onsuccess = function() {console.log('request: ', request.result);db = this.result;// 删const transaction = db.transaction('teacher', 'readwrite');const store = transaction.objectStore('teacher');const res = store.delete(2); // 删除id为2的那条数据res.onerror = function() {console.log('add data error: ', res.error);}res.onsuccess = function() {console.log('add data success...');}
}

修改对象库中的某条数据。

如果已经存在,就修改值;

如果不存在,就添加到对象库中。

注意,该方法是用于修改整条数据的内容,而不是修改数据中某个字段的值。

如果需要修改某个字段的值,可以使用对象库遍历方法。

语法:

const res = store.put(data);
res.onerror = function() {console.log('update data error: ', res.error);
}
res.onsuccess = function() {// result表示当前更新的数据的keyPath值console.log('update data success: ', res.result);
}

示例:

request.onsuccess = function() {console.log('request: ', request.result);db = this.result;// 改const transaction = db.transaction('teacher', 'readwrite');const store = transaction.objectStore('teacher');const res = store.put({id: 1, name: 'dilireba', age: 18});res.onerror = function() {console.log('put data error: ', res.error);}res.onsuccess = function() {console.log('put data success...', res.result); // 1}
}

查询某条对应keyPath值的数据。

语法:

// id是数据中的keyPath值
const res = store.get(id);
res.onerror = function() {console.log('find data error: ', res.error);
}
res.onsuccess = function() {// result是查询到的数据结果console.log('find data success: ', res.result);
}
// 需要注意的是,查询时,事务权限设置为'readonly'即可。

示例:

request.onsuccess = function() {console.log('request: ', request.result);db = this.result;// 查const transaction = db.transaction('teacher', 'readonly');const store = transaction.objectStore('teacher');const res = store.get(1); // 查id为1的那条数据res.onerror = function() {console.log('put data error: ', res.error);}res.onsuccess = function() {console.log('put data success...', res.result);// {id: 1, name: 'dilireba', age: 18}}
}

清除

清除某个对象库中的所有数据。

语法:

const res = store.clear();
res.onerror = function() {console.log('put data error: ', res.error);
}
res.onsuccess = function() {console.log('put data success...');
}

示例:

request.onsuccess = function() {console.log('request: ', request.result);db = this.result;// 清除const transaction = db.transaction('teacher', 'readwrite');const store = transaction.objectStore('teacher');const res = store.clear();res.onerror = function() {console.log('put data error: ', res.error);}res.onsuccess = function() {console.log('put data success...');}
}

条件查询

根据条件查询到符合条件的所有数据。有三种语法。

注意:事务的处理权限设置为readonly即可。

语法一:查询某个对象库中的所有数据

const res = store.getAll();
res.onerror = function() {console.log('find all datas error: ', res.error);
}
res.onsuccess = function() {// result是所有数据组成的列表[...]console.log('find all datas success: ', res.result);
}

示例:

request.onsuccess = function() {console.log('request: ', request.result);db = this.result;// 条件查询const transaction = db.transaction('teacher', 'readonly');const store = transaction.objectStore('teacher');const res = store.getAll();res.onerror = function() {console.log('put data error: ', res.error);}res.onsuccess = function() {console.log('put data success...: ', res.result);// [{id: 1, name: 'dilireba', age: 18},// {id: 2, name: 'zhaoliying', age: 19},// {id: 3, name: 'liuyifei', age: 20}]}
}

语法二:查询某个对象库中所有符合query条件的数据。

const res = store.getAll(query);
res.onerror = function() {console.log('find all datas error: ', res.error);
}
res.onsuccess = function() {// result是返回的数据组成的列表[...]console.log('find all datas success: ', res.result);
}
// 这里是query参数,是指符合IDBKeyRange筛选条件的一个范围。
// 如果数据中的pathKey的值在这个范围内,就会作为数据返回。
// 以下是query和范围的对应关系:
范围 对应的代码,query
All keys ≥ x IDBKeyRange.lowerBound(x)
All keys > x IDBKeyRange.lowerBound(x, true)
All keys ≤ y IDBKeyRange.upperBound(y)
All keys < y IDBKeyRange.upperBound(y, true)
All keys ≥ x && ≤ y IDBKeyRange.bound (x, y)
All keys > x &&< y IDBKeyRange.bound (x, y, true, true)
All keys > x && ≤ y IDBKeyRange.bound (x, y, true, false)
All keys ≥ x &&< y IDBKeyRange.bound(x, y, false, true)
The key = z IDBKeyRange.only (z)

示例:

request.onsuccess = function() {db = this.result;// 数据中的id值大于等于2const query = IDBKeyRange.lowerBound(2);// 条件查询const transaction = db.transaction('teacher', 'readonly');const store = transaction.objectStore('teacher');const res = store.getAll(query);res.onerror = function() {console.log('get data error: ', res.error);}res.onsuccess = function() {console.log('get data success...: ', res.result);// [{id: 2, name: 'zhaoliying', age: 19},// {id: 3, name: 'liuyifei', age: 20}]}
}

语法三:查询某个对象库中一定条数的符合query条件的数据。

const res = store.getAll(query, count);
res.onerror = function() {console.log('find all datas error: ', res.error);
}
res.onsuccess = function() {// result是返回的数据组成的列表[...]console.log('find all datas success: ', res.result);
}
// count是要获取到的数据条数,必须是在0~2^32 - 1的范围内的数字,超出会报错。

示例:

request.onsuccess = function() {db = this.result;const query = IDBKeyRange.lowerBound(2);// 条件查询const transaction = db.transaction('teacher', 'readonly');const store = transaction.objectStore('teacher');const res = store.getAll(query, 1); // 取符合条件的前1条数据res.onerror = function() {console.log('get data error: ', res.error);}res.onsuccess = function() {console.log('get data success...: ', res.result);// [{id: 2, name: 'zhaoliying', age: 19}]}
}

条件查询keyPath值

语法也是有三条,参数同条件查询。

// 语法一
const res = store.getAllKeys();
// 语法二
const res = store.getAllKeys(query);
// 语法三
const res = store.getAllKeys(query, count);

简单示例:

request.onsuccess = function() {db = this.result;const transaction = db.transaction('teacher', 'readonly');const store = transaction.objectStore('teacher');const res = store.getAllKeys();res.onerror = function() {console.log('get keys error: ', res.error);}res.onsuccess = function() {console.log('get keys success...: ', res.result);// 结果就是id值组成的列表[1, 2, 3] }
}

对象库中数据的条数

查询某个对象库中有多少条数据。

语法有两种。

语法一:获取该对象库中共有多少条数据

const res = store.count();
res.onerror = function() {console.log('count data error: ', res.error);
}
res.onsuccess = function() {console.log('该对象库中一共有' + res.result + '条数据'.);
}

示例:

request.onsuccess = function() {db = this.result;const transaction = db.transaction('teacher', 'readonly');const store = transaction.objectStore('teacher');const res = store.count();res.onerror = function() {console.log('count data error: ', res.error);}res.onsuccess = function() {console.log('count data success...: ', res.result); // 3}
}

语法二:

条件查询,符合某个条件的数据共有多少条。

// 参数query仍然是符合IDBKeyRange筛选条件的一个范围。参考上表。
const res = store.count(query);
res.onerror = function() {console.log('count data error: ', res.error);
}
res.onsuccess = function() {console.log('该对象库中符合query条件的数据一共有' + res.result + '条'.);
}

对象库遍历IDBCursor

IDBCursor接口表示一个游标,用于遍历或迭代数据库中的多条记录。

游标可以理解为下标或者指针,指示需要遍历哪一个索引或者对象存储区。

语法

  1. store.openCursor

该方法用于打开一个游标,开启遍历。

它还可以有传递两个参数store.openCursor(query, direction)

query表示要查询的键或者上面表格中的范围值。可选的。
direction表示游标要移动的方向,有4个值:
- next 默认值。表示下一个,键值从小到大一个个遍历,也就是正序遍历。
- nextunique 正序遍历时,过滤掉重复项,会从重复项中选取较小的那个值。
- prev 表示键值从大到小一个个遍历,也就是倒序遍历。
- prevunique 倒序遍历时,过滤掉重复项。

示例:

request.onsuccess = function() {db = this.result; // 这里是this指向requestconst transaction = db.transaction('teacher', 'readwrite');const store = transaction.objectStore('teacher');const res = store.openCursor(); // 开启遍历res.onerror = function() {console.log('each data error: ', res.error);}res.onsuccess = function() { // 这里面的内容将被遍历执行console.log('each data success...');const cursor = this.result; // 这里的this指向resif(cursor) {console.log('val: ', cursor.value);cursor.continue();} else {console.log('没有更多结果了...');}}
}

示例执行结果:

each data success...
val: {id: 1, name: 'dilireba', age: 18}
each data success...
val: {id: 2, name: 'haha', age: 19}
each data success...
val: {id: 3, name: 'liuyifei', age: 20}
each data success...
val: {id: 4, name: 'lilei', age: 21}
each data success...
val: {id: 5, name: 'hanmeimei', age: 22}
each data success...
val: {id: 6, name: 'lihua', age: 23}
没有更多结果了...

  1. cursor.advance or cursor.continue

该语句不能缺少,不然无法遍历数据。

cursor.advance是表示每一步遍历,要跳过多少个下标
必须填写一个大于0的整数作为参数。

比如当前在teacher对象库中有如下6个数据:

{id: 1, name: 'dilireba', age: 18},
{id: 2, name: 'haha', age: 19}
{id: 3, name: 'liuyifei', age: 20}
{id: 4, name: 'lilei', age: 21}
{id: 5, name: 'hanmeimei', age: 22}
{id: 6, name: 'lihua', age: 23}

advance设置不同的值,会得到不同的结果:

// cursor.advance(1)
// 每次移动一次下标
{id: 1, name: 'dilireba', age: 18},
{id: 2, name: 'haha', age: 19},
{id: 3, name: 'liuyifei', age: 20},
{id: 4, name: 'lilei', age: 21},
{id: 5, name: 'hanmeimei', age: 22},
{id: 6, name: 'lihua', age: 23}
// cursor.advance(2)
// 每次移动2次下标,先遍历id 1, 移动两次,遍历到id 3,以此类推。
{id: 1, name: 'dilireba', age: 18},
{id: 3, name: 'liuyifei', age: 20},
{id: 5, name: 'hanmeimei', age: 22}
// cursor.advance(3)
// 每次移动3次下标,先遍历id 1, 然后移动3次下标,遍历到id 4, 以此类推。
{id: 1, name: 'dilireba', age: 18},
{id: 4, name: 'lilei', age: 21}
cursor.continue是表示挨个遍历。相当于cursor.advance(1)

3)cursor.delete()

无参数。

删除游标位置记录,而不改变游标的位置。可以简单理解为,

用于删除对象库中的某些特定数据。

假定仍然是上述示例中的6条数据,

// 遍历时判断 当id为2时,执行delete操作,删除id为2的这条数据
if(curcor) {if(curcor.value.id === 2) {curcor.delete(); // id为2的数据被删除}
} else {console.log('没有更多的结果了...');
}

4)cursor.update()

更新对象库中当前游标位置的值,可以用于更改特定数据中的某个字段的值。

示例:

// 把id为2的数据中的name值改为'张三'
if(curcor) {if(curcor.value.id === 2) {curcor.update({...curcor.value, name: '张三'});}
} else {// ...
}

按照对象库的数据的keyPath进行遍历

1)语法:

const store = transaction.objectStore('teacher').index(indexKeyPath);

这里必须说说对象库的keyPath和对象库数据的keyPath,刚接触的时候可能造成混淆。


2)为什么会出现不同的keyPath?

一个对象库,比如teacher,里面的数据可能有很多个字段,比如id , name, age, sex, hobby等。

{ id: 1, name: 'dilireba', age: 18, sex: 0, hobby: 'sleep' }

id是对象库的keyPath,也就是说,我们在遍历对象库时,是根据id进行遍历的,

但是实际应用中,我们还可能根据名字name进行遍历,也可能是根据年龄age进行遍历,

为了解决这个问题,就出现了对象库的keyPath和对象库数据的keyPath


3)怎么区分?

示例:

request.onupgradeneeded = function() {console.log('open upgrade...');db = this.result;if(!db.objectStoreNames.contains('teacher')) {const objectStore = db.createObjectStore('teacher', { keyPath: 'id' });objectStore.createIndex('name', 'name', { unique: true });objectStore.createIndex('age', 'age', { unique: false })}
}

在示例中,通过db.createObjectStore创建对象库并设置的keyPath就是对象库的keyPath

也就是此处的id就是对象库teacherkeyPath,遍历对象库,都是根据id的值来遍历的。

而示例中通过objectStore.createIndex创建的nameage,就是数据的keyPath

在遍历对象库中的数据时,也可以通过nameage进行遍历。


4)如何使用数据中的keyPath进行遍历?

语法:

const store = transaction.objectStore('teacher').index(indexKeyPath);

示例1:根据age进行遍历

request.onsuccess = function() {db = this.result; // 这里是this指向requestconst transaction = db.transaction('teacher', 'readwrite');// index('age')const store = transaction.objectStore('teacher').index('age');const res = store.openCursor();res.onerror = function() {console.log('each data error: ', res.error);}res.onsuccess = function() {console.log('each data success...');const cursor = this.result; // 这里的this指向resif(cursor) {console.log('val: ', cursor.value);cursor.continue();} else {console.log('没有更多结果了...');}}
}

示例结果:

{id: 3, name: 'zhangsan', age: 16}
{id: 1, name: 'dilireba', age: 18}
{id: 4, name: 'lilei', age: 21}
{id: 5, name: 'hanmeimei', age: 22}
{id: 6, name: 'lihua', age: 23}
{id: 2, name: 'liuyifei', age: 32}

示例2:根据name进行遍历

request.onsuccess = function() {db = this.result; // 这里是this指向requestconst transaction = db.transaction('teacher', 'readwrite');// index('name')const store = transaction.objectStore('teacher').index('name');const res = store.openCursor();res.onerror = function() {console.log('each data error: ', res.error);}res.onsuccess = function() {console.log('each data success...');const cursor = this.result; // 这里的this指向resif(cursor) {console.log('val: ', cursor.value);cursor.continue();} else {console.log('没有更多结果了...');}}
}

示例结果:

{id: 1, name: 'dilireba', age: 18}
{id: 5, name: 'hanmeimei', age: 22}
{id: 6, name: 'lihua', age: 23}
{id: 4, name: 'lilei', age: 21}
{id: 2, name: 'liuyifei', age: 32}
{id: 3, name: 'zhangsan', age: 16}

学习资料

  • MDN

    https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
    
  • IndexedDB阮一峰

    https://www.ruanyifeng.com/blog/2018/07/indexeddb.html
    

【indexedDB】indexedDB知识梳理相关推荐

  1. 插件化知识梳理(7) 类的动态加载入门

    一.前言 在 插件化知识梳理(6) - Small 源码分析之 Hook 原理 这一章的学习完成之后,下一步我们将进入插件化加载的精髓,动态加载类的学习,在此之前,我们需要先准备一些关于类加载的知识. ...

  2. 数据结构(C语言版) 第 八 章 排序 知识梳理 + 习题详解

    目录 一.归并排序 二.交换排序 1.快速排序 2.冒泡排序 三.插入排序 1.直接插入排序(基于顺序查找) 2.折半插入排序(基于折半查找) 3.希尔排序(基于逐趟缩小增量) 四.选择排序 0.直接 ...

  3. 数据结构(C语言版) 第 六 章 图 知识梳理 + 习题详解

    目录 一. 图的基本定义和术语 一.图的基本概念 1.度 2.连通 (1)连通图 (2)强连通/强连通图 3.回路 4.完全图 二.图的三种存储结构 1.邻接矩阵表示法 2.邻接表(链式)表示法 3. ...

  4. 数据结构(C语言版) 第 三 章 栈与队列 知识梳理 + 作业习题详解

    目录 一.栈 0.栈的基本概念 1.栈的实现 2.栈与递归 3.Hanoi塔问题 二.队列 0.队列的基本概念 1.队列的实现 2.循环队列 2.1循环队列的相关条件和公式: 3.链队列 4.链队列完 ...

  5. 数据结构(C语言版) 第二章 线性表 知识梳理+作业习题详解

    目录 一.线性表顺序存储结构(顺序表) 0.线性表的基本概念 1.样例引入:多项式相加 二.线性表链式存储结构(链表) 0.链表的基本概念 1.前插法代码实例 2.链表尾插法完整代码附带各种操作 三. ...

  6. Framework 源码解析知识梳理(5) startService 源码分析

    一.前言 最近在看关于插件化的知识,遇到了如何实现Service插件化的问题,因此,先学习一下Service内部的实现原理,这里面会涉及到应用进程和ActivityManagerService的通信, ...

  7. Python基础知识梳理(一)

    Python基础知识梳理: 转载于:https://blog.51cto.com/10412806/2095116

  8. C#基础知识梳理系列十:异常处理 System.Exception

    C#基础知识梳理系列十:异常处理 System.Exception 参考文章: (1)C#基础知识梳理系列十:异常处理 System.Exception (2)https://www.cnblogs. ...

  9. python语法基础知识总结-Python基础知识梳理 - 第01部分

    在开始Python基础知识梳理前, 先安装下环境. 以下过程是在Linux操作系统, root用户下进行的, 主要安装了2.7版本的python, 和pip, ipython, virtualenv等 ...

  10. Dagger2 知识梳理(1) Dagger2 依赖注入的两种方式

    一.资料推荐 最近这几天一直在看有关Dagger2有关的文章,感觉就是这东西真难用.真难懂,数次想要放弃,还好有网上大神的教程帮助,模模糊糊总算能把基本的几个概念跑通了. 这里首先推荐 牛晓伟 的下面 ...

最新文章

  1. 实现3d图片移动_ThingJS官方示例(三):3D标记Marker动效定制化
  2. 机器人研究员的崛起 |《自然》论文
  3. golang二维数组初始化
  4. NYOJ 586 疯牛
  5. 离线安装gcc(CentOS7)
  6. git安装后设置用户名和密码
  7. 最简单的List集合排序方法
  8. iOS设计模式解析(三)适配器模式
  9. win10+Ubuntu18.04双系统安装后无法进入win10或者无法进入Ubuntu的解决方案
  10. IE白屏修复,vue 兼容IE
  11. 打印机软件未通过电脑测试,打印机测试错误 原因administrator解决办法
  12. 巴菲特致股东的信pdf_股神巴菲特发布致股东公开信,接班人仍是个谜
  13. 协同办公市场暴增背后:融云通信能力是需求重点
  14. 计算机图形学VC 配置,计算机图形学(VC++实现)(第2版)
  15. EF Attatch()方法附加对象
  16. 简洁,简单,再简化...
  17. set up ovn development env (by quqi99)
  18. maven 服务器自动打包,Maven 打包项目到私服 (deploy)的配置方法
  19. QPaintEvent 与 画家QPainter
  20. 序言 互联网金融第二弹

热门文章

  1. PS流(ISO13818和GB28181)分析
  2. GitHub实现邀请他人一起协作
  3. 翁刚c语言,每小题3分,共计12分。  ——青夏教育精英家教网——
  4. APP推广案例之星巴克APP营销方式
  5. JSON解析格式化工具——非插件(超好用推荐)
  6. python两列时间间隔计算器_在python中有效地比较两列中的每对日期
  7. pyltp学习笔记——中文语言处理工具
  8. 会声会影2020秘钥视频编辑制作使用教程
  9. 华为服务器插键盘的位置,服务器键盘重启
  10. 技巧 | 使用基础绘图系统绘制「森林图」